本文先介绍Java
的内存管理,以及导致Java
内存泄露的原因。
一. Java
是如何管理内存
为了判断Java
中是否有内存泄露,我们首先必须了解Java
是如何管理内存的。Java
的内存管理就是对象的分配和释放问题。在Java
中,内存 的分配是由程序完成的,而内存的释放是由垃圾收集器(Garbage Collection
,GC)
完成的,程序员不需要通过调用函数来释放内存,但它只能回收无用并且不再被其它对象引用的那些对象所占用的空间。
Java
的内存垃圾回收机制是从程序的主要运行对象开始检查引用链,当遍历一遍后发现没有被引用的孤立对象就作为垃圾回收。GC
为了能够正确释放对 象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC
都需要进行监控。监视对象状态是为了更加准确地、及时地释放对象,而释放 对象的根本原则就是该对象不再被引用。
在Java
中,这些无用的对象都由GC
负责回收,因此程序员不需要考虑这部分的内存泄露。虽然,我们有几个函数可以访问GC
,例如运行GC
的函数 System.gc()
,但是根据Java
语言规范定义,该函数不保证JVM
的垃圾收集器一定会执行。因为不同的JVM
实现者可能使用不同的算法管理 GC
。通常GC
的线程的优先级别较低。JVM
调用GC
的策略也有很多种,有的是内存使用到达一定程度时,GC
才开始工作,也有定时执行的,有的是平缓执行 GC
,有的是中断式执行GC
。但通常来说,我们不需要关心这些。
二.
什么是Java
中的内存泄露
导致内存泄漏主要的原因是,先前申请了内存空间而忘记了释放
。如果程序中存在对无用对象的引用,那么这些对象就会驻留内存,消耗内存,因为无法让垃
圾回收器GC
验证这些对象是否不再需要。如果存在对象的引用,这个对象就被定义为"
有效的活动"
,同时不会被释放。要确定对象所占内存将被回收,我们就要 务必确认该对象不再会被使用。典型的做法就是把对象数据成员设为null
或者从集合中移除该对象。但当局部变量不需要时,不需明显的设为null
,因为一个方法执行完毕时,这些引用会自动被清理。
在Java
中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是有被引用的,即在有向树形图中,存在树枝通路可以与其
相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java
中的内存泄漏,这些对象不会被GC
所回收,然而它却占用内存。
这里引用一个常看到的例子,在下面的代码中,循环申请Object
对象,并将所申请的对象放入一个Vector
中,如果仅仅释放对象本身,但因为 Vector
仍然引用该对象,所以这个对象对GC
来说是不可回收的。因此,如果对象加入到Vector
后,还必须从Vector
中删除,最简单的方法就是 将Vector
对象设置为null
。
1.
Vector v = new
Vector(10
);
2.
for
(int
i = 1
; i < 100
; i++)
3.
{
4.
Object o = new
Object();
5.
v.add(o);
6.
o = null
;
7.
}//
此时,所有的Object
对象都没有被释放,因为变量v
引用这些对象。
实际上这些对象已经是无用的,但还被引用,GC
就无能为力了(
事实上GC
认为它还有用)
,这一点是导致内存泄漏最重要的原因。 再引用另一个例子来说明Java
的内存泄漏。假设有一个日志类Logger
,其提供一个静态的log(String msg)
,任何其它类都可以调用Logger.Log(message)
来将message
的内容记录到系统的日志文件中。
Logger
类有一个类型为HashMap
的静态变量temp
,每次在执行log(message)
的时候,都首先将message
的值写入 temp
中(
以当前线程+
当前时间为键)
,在退出之前再从temp
中将以当前线程和当前时间为键的条目删除。注意,这里当前时间是不断变化的,所以log
在退出之前执行删除条目的操作并不能删除执行之初写入的条目。这样,任何一个作为参数传给log
的字符串最终由于被Logger
的静态
变量temp
引用
, 而无法得到回收,这种对象保持就是我们所说的Java
内存泄漏。
总的来说,内存管理中的内存泄漏产生的主要原因:保留下来却永远不再使用的对象引用。
转自:http://developer.51cto.com/art/200906/129353.htm
总结:
程序中造成内存溢出可能性最大的是
HashMap
,
Hashtable
等集合类,尤其是静态的.
解决办法:彻底删除键,
remove
、
clear
,如果允许最好把集合对象设为
null
分享到:
相关推荐
### 如何解决Java内存泄漏 #### 1. 背景 Java凭借其垃圾回收机制大大简化了内存管理,使得开发者无需手动管理内存的释放,从而提升了开发效率。然而,这种自动化管理也可能成为一把双刃剑,特别是当开发人员忽视...
本文将深入探讨如何检测和分析Java内存泄露与溢出,并介绍一种常用的工具——Memory Analyzer(MAT)。 首先,理解内存泄露的概念至关重要。在Java中,内存泄露通常发生在对象不再被程序使用但仍然保持在内存中,...
Java内存泄漏是一个严重的问题,它会导致程序性能下降,甚至可能导致应用程序崩溃。为了有效地诊断和解决这类问题,开发者需要借助特定的分析工具。本篇将详细探讨Java内存泄漏及其相关的分析工具。 内存泄漏是指...
### Java内存泄漏解决方案详解 #### 一、Java内存泄漏概述 在Java开发过程中,经常会遇到内存泄漏的问题,尤其是在长时间运行的应用程序中更为常见。本文将详细介绍如何解决Java内存泄漏问题,帮助开发者更好地...
Java内存泄漏分析是一个关键的系统优化任务,尤其是在大型企业级应用中,长期运行的系统可能会因为内存泄漏导致性能下降甚至服务中断。"JAVA内存泄漏分析工具"正是一款用于解决此类问题的专业工具,它能帮助开发者...
本文将深入探讨Java内存泄露的原理,分析内存无法回收的原因,并提供相应的解决方案。 首先,我们要了解Java内存模型。Java虚拟机(JVM)中有三个主要的内存区域:堆内存(Heap)、栈内存(Stack)和方法区(Method...
4. "java内存泄露专题研究和应用_石麟.docx"可能提供了更深入的研究和实际案例,包括如何识别特定类型的内存泄漏,以及针对不同场景下的解决方案。而"ha450.jar"可能是一个示例应用或者工具,用于演示内存泄漏问题...
通过深入理解Java内存管理机制,掌握内存泄漏的常见原因及其检测与避免方法,可以帮助开发者构建出更加高效稳定的应用程序。特别是在服务器端应用和嵌入式系统中,内存泄漏可能导致严重后果,因此对内存管理的重视尤...
在探讨Java内存泄漏之前,我们先简要回顾一下JVM(Java虚拟机)的基本架构及其内存管理机制。这有助于更好地理解内存泄漏的发生原因及其解决方法。 ##### 类装载子系统 类装载子系统负责加载Java类,并将其转换为...
标题“Java加载dll,导致Java进程内存泄露”涉及到的是Java平台与本地库(DLL)交互时可能出现的问题。在Java中,通过Java Native Interface (JNI) 可以调用C/C++编写的动态链接库(DLL),实现Java代码与本地代码的...
Java内存泄露检测是Java...总之,Java内存泄露检测是一个涉及编程规范、内存管理原理、内存泄露类型以及检测方法的综合问题。通过深入理解和实践,开发者可以有效地防止和解决内存泄露问题,提高程序的健壮性和性能。
本文将深入探讨Java内存泄露的原因、表现形式以及预防措施。 #### 二、Java内存回收机制 Java的内存管理机制主要依赖于垃圾回收器(Garbage Collection, GC),这是一种自动化的内存管理方式。当对象不再被引用时,...
本文将深入探讨Java内存分析和内存泄露问题。 首先,我们需要了解Java内存模型的基础。Java内存主要分为三个区域:堆(Heap)、栈(Stack)和方法区(Method Area)。堆用于存储对象实例,栈用于存储方法调用及局部...
标题提到的"java内存泄露分析工具 eclipse3.5插件"正是指Eclipse Memory Analyzer与Eclipse IDE 3.5版本的集成。 Eclipse Memory Analyzer(MAT)通过分析heap dump文件来识别可能的内存泄露。Heap dump是Java...
"Java内存泄露_JVM监控工具介绍" Java内存泄露是Java开发中常见的一种问题,发生内存泄露可能会导致Java应用程序崩溃或性能下降。在Java中,内存泄露的原因非常多样,例如,静态变量、循环引用、数据库连接池、...
Java内存管理是一个关键的议题,尤其对于开发大型和长期运行的应用程序来说,内存泄漏可能导致性能下降,甚至引发严重的系统故障。内存泄漏通常发生在程序错误地管理内存,导致某些不再使用的对象无法被垃圾收集器...
java内存泄露定位与分析