background image

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);