Thinking In Java 5.5 清理:终结处理和垃圾回收

垃圾回收器

java垃圾回收器负责回收无用对象占据的内存资源。对于不是由 new 产生的”特殊”对象内存区域,垃圾回收器是不知道如何释放该对象的这块”特殊”内存。为了应对这种情况,java允许在类中定义一个名为finalize()方法。

finalize方法的工作原理: 在java垃圾回收器准备回收对象的内存时,它会首先调用对象的finalize()方法,并在下一次垃圾回收动作中真正回收对象占据的内存。

垃圾回收3要点:

  • 对象不可能不被垃圾回收
  • 垃圾回收并不等于”析构”
  • 垃圾回收只与内存有关

finalize() 的几种使用方法:

  • C/C++ 的native方法的内存创建,可以再finalize中使用 native的Delete方法释放,以免泄露
  • 终结条件验证,当对象将要被清理之前,可以验证终结条件是否满足。

触发GC的条件

  • 手动强制调用 System.gc()。
  • 当堆内存不足的时候,会自动调用gc。
  • 当应用程序空暇时或者挂起后台时,会调用gc。

降低GC开销的措施

依据上述GC的机制,程序的执行会直接影响系统环境的变化,从而影响GC的触发。

若不针对GC的特点进行设计和编码,就会出现内存驻留等一系列负面影响。为了避免这些影响,主要的原则就是尽可能地降低垃圾和降低GC过程中的开销。

详细措施包含下面几个方面:

  (1)不要显式调用System.gc()

  此函数建议JVM进行主GC,尽管仅仅是建议而非一定,但非常多情况下它会触发主GC,从而添加主GC的频率,也即添加了间歇性停顿的次数。

  (2)尽量降低暂时对象的使用

  暂时对象在跳出函数调用后,会成为垃圾,少用暂时变量就相当于降低了垃圾的产生,从而延长了出现上述第二个触发条件出现的时间,降低了主GC的机会。

  (3)对象不用时最好显式置为Null

  一般而言,为Null的对象都会被作为垃圾处理,所以将不用的对象显式地设为Null,有利于GC收集器判定垃圾,从而提高了GC的效率。

  (4)尽量使用StringBuffer,而不用String来累加字符串

  因为String是固定长的字符串对象,累加String对象时,并不是在一个String对象中扩增,而是又一次创建新的String对象,如Str5=Str1+Str2+Str3+Str4,这条语句执行过程中会产生多个垃圾对象,因为对次作“+”操作时都必须创建新的String对象,但这些过渡对象对系统来说是没有实际意义的,仅仅会添加很多其它的垃圾。

避免这样的情况能够改用StringBuffer来累加字符串,因StringBuffer是可变长的,它在原有基础上进行扩增,不会产生中间对象。

  (5)能用基本类型如Int,Long,就不用Integer,Long对象

  基本类型变量占用的内存资源比对应对象占用的少得多,假设没有必要,最好使用基本变量。

  (6)尽量少用静态对象变量

  静态变量属于全局变量,不会被GC回收,它们会一直占用内存。

  (7)分散对象创建或删除的时间

  集中在短时间内大量创建新对象,特别是大对象,会导致突然须要大量内存,JVM在面临这样的情况时,仅仅能进行主GC,以回收内存或整合内存碎片,从而添加主GC的频率。集中删除对象,道理也是一样的。

它使得突然出现了大量的垃圾对象,空暇空间必定降低,从而大大添加了下一次创建新对象时强制主GC的机会。

垃圾收集和原理和算法分析

在此为简单介绍,日后带来详细分析。

垃圾回收作用: 1.发现无用的信息对象 ,2.回收被无用对象所占据的内存空间。

猜你喜欢

转载自blog.csdn.net/xiaocajiyyd/article/details/79126039