qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

Java内存回收机制

一、Java对象在内存引用状态
  内存泄露:程序运行过程中,会不断分配内存空间,那些不再使用的内存空间应该即时回收它们,从而保证系统可以再次使用这些内存,如果存在无用的内存没有被回收回来,这就是内存泄漏.
  (1)强引用
  这是java程序中最常见的引用方式,程序创建一个对象,并把这个对象赋给一个引用变量,这个引用变量就是强引用.java程序可通过强引用来访问实际的对象。当一个对象被一个或一个以上的强引用变量引用时,它处于可达状态,它不可能被系统垃圾回收机制回收。
  强引用是Java编程中广泛使用的引用类型,被强引用所引用的Java对象绝不会被垃圾回收机制回收,即使系统内存紧张;即使有些Java对象以后永远也不会被用到,JVM也不会回收被强引用所引用的Java对象.
  由于JVM肯定不会回收强引用所引用的JAVA对象,因此强引用是造成JAVA内存泄漏的主要原因。
  如 ReceiptBean rb=new ReceiptBean(); rb就代表了一种强引用的方式
  (2)软引用
  软引用需要通过SoftReference类来实现,当一个对象只具有软引用时,它可能被垃圾回收机制回收。对于只有软引用的对象而言,当系统内存空间足够时,它不会被系统回收,程序也可以使用该对象;当系统内存空间不足时,系统将回收它.
  软引用通常用在对内存敏感的程序中,软引用是强引用很好的替代。对于软引用,当系统内存空间充足时,软引用与强引用没有太大的区别,当系统内存空间不足时,被软引用所引用的JAVA对象可以被垃圾回收机制回收,从而避免系统内存不足的异常.
  当程序需要大量创建某个类的新对象,而且有可能重新访问已创建老对象时,可以充分使用软引用来解决内存紧张的问题。
  例如需要访问1000个Person对象,可以有两种方式
  方法一 依次创建1000个对象,但只有一个Person引用指向最后一个Person对象
  方法二 定义一个长度为1000个的Person数组,每个数组元素引用一个Person对象.
  对于方法一,弱点很明显,程序不允许需要重新访问前面创建的Person对象,即使这个对象所占的空间还没有被回收。但已经失去了这个对象的引用,因此也不得不重新创建一个新的Person对象(重新分配内存),而那个已有的Person对象(完整的,正确的,可用的)则只能等待垃圾回收
  对于方法二,优势是可以随时重新访问前面创建的每个Person对象,但弱点也有,如果系统堆内存空间紧张,而1000个Person对象都被强引用引着,垃圾回收机制也不可能回收它们的堆内存空间,系统性能将变成非常差,甚至因此内存不足导致程序中止。
  如果用软引用则是一种较好的方案,当堆内存空间足够时,垃圾回收机制不会回收Person对象,可以随时重新访问一个已有的Person对象,这和普通的强引用没有任何区别。但当heap堆内存空间不足时,系统也可以回收软引用引用的Person对象,从而提高程序运行性能,避免垃圾回收.
  当程序使用强引用时,无论系统堆内存如何紧张,JVM垃圾回收机制都不会回收被强引用所引用的Java对象,因此最后导致程序因内存不足而中止。但如果把强引用改为软引用,就完成可以避免这种情况,这就是软引用的优势所在.
  (3)弱引用
  弱引用与软引用有点相似,区别在于弱引用所引用对象的生存期更短。弱引用通过WeakReference类实现,弱引用和软引用很像,但弱引用的引用级别更低。对于只有弱引用的对象而言,当系统垃圾回收机制运行时,不管系统内存是否足够,总会回收该对象所占用的内存。当然,并不是说当一个对象只有弱引用时,它就会立即被回收,正如那些失去引用的对象一样,必须等到系统垃圾回收机制运行时才会被回收.
  总结说明:
  1.弱引用具有很大的不确定性,因为每次垃圾回收机制执行时都会回收弱引用所引用的对象,而垃圾回收机制的运行又不受程序员的控制,因此程序获取弱引用所引用的java对象时必须小心空指针异常,通过弱引用所获取的java对象可能是null
  2.由于垃圾回收的不确定性,当程序希望从弱引用中取出被引用对象时,可能这个被引用对象已经被释放了。如果程序需要使用被引用的对象,则必须重新创建该对象。
  (4)虚引用
  软引用和弱引用可以单独使用,但虚引用不能单独使用,单独使用虚引用没有太大的意义。虚引用的主要作用就是跟踪对象被垃圾回收的状态,程序可以通过检查虚引用关联的引用队列中是否包含指定的虚引用,从而了解虚引用所引用的对象是否将被回收.
  引用队列由java.lang.ref.ReferenceQueue类表示,它用于保存被回收对象的引用。当把软引用,弱引用和引用队列联合使用时,系统回收被引用的对象之后,将会把被回收对象对应的引用添加到关联的引用队列中。与软引用和弱引用不同的是,虚引用在对象被释放之前,将把它对应的虚引用添加到关联的队列中,这使得可以在对象被回收之前采取行动。
  虚引用通过PhantomReference类实现,它完全类似于没有引用。虚引用对对象本身没有大的影响,对象甚至感觉不到虚引用的存在。如果一个对象只有一个虚引用,那它和没有引用的效果大致相同。虚引用主要用于跟踪对象被垃圾回收的状态,虚引用不能单独使用,虚引用必须和队列ReferenceQueue联合使用.


posted on 2013-11-15 11:12 顺其自然EVO 阅读(192) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航:
 
<2013年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜