1
Vector v=
new
Vector(10);
2
for
(
int
i=1;i<100; i++){
3
Object o=
new
Object();
4
v.add(o);
5
o=
null
;
6
}
在这个例子中,代码栈中存在 Vector 对象的引用 v 和 Object 对象的引用 o。在 For 循
环中,我们不断的生成新的对象,然后将其添加到 Vector 对象中,之后将 o 引用置空。
问题是当 o 引用被置空后,如果发生 GC,我们创建的 Object 对象是否能够被 GC 回收
呢?答案是否定的。因为,GC 在跟踪代码栈中的引用时,会发现 v 引用,而继续往下跟
踪,就会发现 v 引用指向的内存空间中又存在指向 Object 对象的引用。也就是说尽管 o
引用已经被置空,但是 Object 对象仍然存在其他的引用,是可以被访问到的,所以 GC
无法将其释放掉。如果在此循环之后,Object 对象对程序已经没有任何作用,那么我们
就认为此 Java 程序发生了内存泄漏。
尽管对于 C/C++中的内存泄露情况来说,Java 内存泄露导致的破坏性小,除了少数
情况会出现程序崩溃的情况外,大多数情况下程序仍然能正常运行。但是,在移动设备对
于内存和 CPU 都有较严格的限制的情况下,Java 的内存溢出会导致程序效率低下、占用
大量不需要的内存等问题。这将导致整个机器性能变差,严重的也会引起抛出
OutOfMemoryError,导致程序崩溃。
一般情况下内存泄漏的避免
在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周
“
”
期超出了程序需要它的时间长度。我们有时也将其称为 对象游离 。
例如:
1
public
class
FileSearch{
2
3
private
byte
[] content; 有问题
,不应该被声明为实例变量
4
private
File mFile;
5
6
public
FileSearch(File file){
7
mFile = file;
8
}
9
10
public
boolean
hasString(String str){
11
int
size = getFileSize(mFile);
12
content =
new
byte
[size];
13
loadFile(mFile, content);
14
15
String s =
new
String(content);
16
return
s.contains(str);