Java 垃圾回收和注意事项

来源:互联网 发布:深圳公务员 知乎 编辑:程序博客网 时间:2024/06/14 10:08

1.影响java垃圾回收

Person p = new Person(“aaa”);
p = new Person(“bbb”);
这样,new Person(“aaa”)这个对象就是垃圾了—-符合垃圾回收条件了。

2.让相互联系的对象称为“岛”对象
Person p1 = new Person(“aaa”);
Person p2 = new Person(“bbb”);
Person p3 = new Person(“ccc”);
p1=p2; p2=p3; p3=p1;
p1=null; p2=null; p3=null;
没有对p1、p2、p3置null之前,它们之间是一种三角恋关系。分别置null,三角恋关系依然存在,但是三个变量不在使用它们了。三个Person对象就组成了一个孤岛,最后死在堆上—-被垃圾回收掉。

3.强制的垃圾回收System.gc()
System.gc()
上面的方法用于显式的通知JVM可以进行一次垃圾回收,但真正垃圾回收机制具体在什么时间点开始进行垃圾回收是不可预料的;唯一能保证的是当你内存在极少的情况,垃圾回收器在程序抛出OutofMemaryException之前运行一次。

开发中常用的减少GC开销的措施

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

此函数建议JVM进行主GC,虽然只是建议而非一定,但很多情况下它会触发主GC,从而增加主GC的频率,也即增加了间歇性停顿的次数。这里特别需要说明的是,在代码中显示的调用System.gc(),并不一定能够进行GC,这个我们可以通过finalize()方法进行验证,即主动调用System.gc(),并不一定每次都调用finalize()方法。finalize()方法的特征是在对象被回收之前, 首先调用finalize()方法。

(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对象

基本类型变量占用的内存资源比相应对象占用的少得多,如果没有必要,最好使用基本变量。什么情况下需要使用Integer?

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

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

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

集中在短时间内大量创建新对象,特别是大对象,会导致突然需要大量内存,JVM在面临这种情况时,只能进行主GC,以回收内存或整合内存碎片, 从而增加主GC的频率。集中删除对象,道理也是一样的。它使得突然出现了大量的垃圾对象,空闲空间必然减少,从而大大增加了下一次创建新对象时强制主GC 的机会。 
0 0
原创粉丝点击