垃圾收集算法的核心思想(2)

 

5.Java 存泄漏
  由于采用了圾回收机制,任何不可达对(象不再被引用)都可以由圾收集线程回收。因此通常Java 存泄漏其是指无意的、非故意的象引用,或者无意象保持。无意象引用是指代开发经对对象使用完,却因为编码错误而意外地保存了对该对象的引用(这个引用的存在不是编码的主意愿)而使得该对象一直无法被圾回收器回收掉,这种可以放掉的却最未能被放的空可以认为是被泄漏了

  考下面的程序,ObjStack,使用pushpop方法管理堆中的象。两个方法中的索引(index)用于指示堆中下一可用位置。push方法存储对象的引用增加索引,pop方法小索引值并返回堆最上面的元素。在main方法中,建了容量64,64push方法向添加,index值为64,后又32pop方法,index值变为32,意味着在堆中的空间应该被收集。但事,pop方法只是小了索引,仍然保持着那些象的引用。故32无用象不GC回收,造成了存渗漏。

 

java

1.    public class ObjStack {    

2.       private Object[] stack;  

3.       private int index;  

4.       ObjStack(int indexcount) {  

5.       stack = new Object[indexcount];  

6.       index = 0;  

7.       }  

8.       public void push(Object obj) {  

9.       stack[index] = obj;  

10.     index++;  

11.     }  

12.     public Object pop() {  

13.     index--;  

14.     return stack[index];  

15.     }  

16.     }  

17.     public class Pushpop {  

18.     public static void main(String[] args) {  

19.     int i = 0;  

20.     Object tempobj;  

21.    

22.  //newObjStack象,并调用有参构造函。分配stack Obj数组的空大小64,可以存64个对象,0始存  

23.     ObjStack stack1 = new ObjStack(64);  

24.    

25.     while (i < 64)  

26.     {  

27.     tempobj = new Object();//new Obj象,把每次循象一一存放在stack Obj数组中。   

28.     stack1.push(tempobj);  

29.     i++;  

30.     System.out.println("" + i + "进栈" + "/t");  

31.     }  

32.    

33.     while (i > 32)  

34.     {  

35.     tempobj = stack1.pop();//里造成了空的浪   

36.     //正确的pop方法可改成如下所指示,引用被返回后,栈删的引用,因此圾收集器在以后可以回收他   

37.     /*  

38.     * public Object pop() {index - -;Object temp = stack [index];stack [index]=null;return temp;}  

39.     */  

40.     i--;  

41.     System.out.println("" + (64 - i) + "次出" + "/t");  

42.     }  

43.     }  

44.     } 

 

6.如何消除存泄漏

  Java虚拟(JVM)及其圾收集器(garbage collectorGC)负责管理大多存任Java件程序中是有可能出现内存泄漏。实际上,在大型目中是一问题。避免存泄漏的第一步是要弄是如何生的。本文介编写Java的一些常存泄漏陷,以及编写不泄漏代的一些最佳实践。一旦生了存泄漏,要指出造成泄漏的代是非常困的。因此本文了一新工具,用来诊断泄漏指出根本原因。工具的开销非常小,因此可以使用它来寻于生中的系存泄漏。

  圾收集器的作用

  圾收集器理了大多数内存管理问题而使程人的生活得更松了,但是程人员还是可能犯致出现内问题简单GC地跟踪所有(栈对象、静态对象、JNI句柄指向的象,如此)的引用,并将所有能到标记为的。程序只可以操纵这;其他的象都被除了。因GC使程序不可能到已被除的象,这么做就是安全的。

  存管理可以是自化的,但是这并不能使程人免受思考存管理问题之苦。例如,分配(以及)总会开销这种开销对编程人员来说是不可的。建了太多象的程序将会比完成同的功能而建的象却比少的程序更慢一些(在其他件相同的情)

  而且,本文更密切相的是,如果忘先前分配的存,就可能造成存泄漏。如果程序保留不再使用的象的引用,将会占用尽内存,是因化的圾收集器无法不再使用。正如我先前所的,如果存在一个对对象的引用,象就被定义为的,因此不能除。了确保能回收象占用的存,程人确保该对象不能到通常是通过将对象字段null或者集合(collection)中移除象而完成的。但是,注意,局部量不再使用有必要式地null对这量的引用将随着方法的退出而自动清除。

  括地就是存托管言中的存泄漏生的主要原因:保留下却永不再使用的象引用。

  典型泄漏

  然我知道了在Java中确有可能存泄漏,就们来看一些典型的存泄漏及其原因。

  全局集合

  在大的用程序中有某全局的是很常的,例如一JNDI或一个会话表。在些情下,必注意管理的大小。必有某机制从储中移除不再需要的据。

  可能有多方法,但是最常的一是周期性行的某种清除任务将验证储中的据,移除任何不再需要的据。

  另一管理的方法是使用反向(referrer)计数。然后集合负责统计集合中每入口的反向接的目。要求反向接告集合何时会退出入口。反向元素就可以集合中移除了。

  

  存是一种数结构,用于快速找已经执行的操作的果。因此,如果一操作行起很慢,于常用的据,就可以操作的存,在下次操作使用存的据。

  存通常都是以动态方式实现的,其中新的果是在添加到存中的。典型的算法是:

  检查结果是否在存中,如果在,就返回果。

  如果果不在存中,就算。

  将计算出果添加到存中,以便以后对该操作的用可以使用。

  算法的问题(或者是潜在的存泄漏)出在最后一步。如果操作有相多的不同入,就有相多的果存存中。很明显这不是正确的方法。

  这种具有潜在破坏性的设计,程序必确保存所使用的存容量有一上限。因此,更好的算法是:

  检查结果是否在存中,如果在,就返回果。

  如果果不在存中,就算。

  如果存所占的空间过大,就移除存最久的果。

  将计算出果添加到存中,以便以后对该操作的用可以使用。

  通移除存最久的果,我们实际行了这样的假:在将来,比起存最久的据,最近入的据更有可能用到。通常是一的假

  新算法确保存的容量存范。确切的范可能很难计算,因为缓存中的象在不断变化,而且它们的引用包万象。为缓置正确的大小是一非常复杂的任,需要所使用的存容量与检据的速度加以平衡。

  解决这个问题的另一方法是使用java.lang.ref.SoftReference跟踪存中的象。这种方法保证这些引用能被移除,如果虚拟机的存用而需要更多堆的

  ClassLoader

  Java ClassLoader结构的使用为内存泄漏提供了多可乘之机。正是该结构本身的复杂性使ClassLoader存泄漏方面存在如此多的问题ClassLoader的特在于涉及象引用,涉及元象引用,比如:字段、方法和意味着只要有字段、方法、ClassLoader象的引用,ClassLoader会驻留在JVM中。因ClassLoader本身可以关联许及其静态字段,所以就有存被泄漏了。

  确定泄漏的位置

  通常存泄漏的第一迹象是:在用程序中出OutOfMemoryError通常生在最不愿意它发生的生产环境中,此几乎不能调试。有可能是因为测试环用程序的方式不完全相同,因而致泄漏只出在生中。在这种下,需要使用一些开销较低的工具来监控和存泄漏。需要能无需重或修改代就可以将这些工具接到正在行的系上。可能最重要的是,当进行分析,需要能够断开工具而保持系不受干

  OutOfMemoryError通常都是存泄漏的信,但是也有可能用程序确正在使用这么多的;于后者,或者必增加JVM可用的堆的量,或者对应用程序行某更改,使使用少的存。但是,在多情下,OutOfMemoryError都是存泄漏的信。一种查明方法是不间断GC的活,确定存使用量是否时间增加。如果确如此,就可能生了存泄漏

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值