2008年9月7日星期日

JVM_007:哪些代码会影响 GC?(摘录+整理)

1. 不要使用如下方法:
(1)Object.finalize():Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. 该方法用来回收内存以外的系统资源,比如文件句柄和网络连接。
(2)System.gc():Runs the garbage collector. 该方法建议JVM执行GC(
major collection,可以使用-XX:+DisableExplicitGC禁止它,或设为CMS并发-XX:+ExplicitGCInvokesConcurrent。
(3)System.runFinalization():Runs the finalization methods of any objects pending finalization.

2. 分配给应用程序的内存越多越好?错,应该按需分配,绝不多给
你应该考虑的问题是你的应用程序需要多少内存?这个话题扯远了,留待以后再说。

3. 不用的变量显式置为null
将不用的变量显式地设为Null,有利于GC收集该变量所引用的对象。注意:
(1)对于局部变量不用设置为null,因为这些变量的引用将随着方法的退出而自动清除。
(2)如果该对象与事件监听器有连接,那它还是不可以被收集。因此在设置一个引用变量为null之前,应注意该引用变量指向的对象是否被监听,若有,要首先除去监听器,然后才可以设置为null。
(3)不要滥用这一条建议。滥用的结果可能适得其反。例如,迭代地或者递归地赋空集合内的元素使得这些集合中的对象能够满足垃圾收集的条件,实际上是增加了系统的开销而不是帮助垃圾收集。
正确的做法是正确地设置变量的作用域,而不要显式地赋空它们。

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

5. 如果可以,使用WeakReference或SoftReference
WeakReference是真正意义上的C++指针,只是单纯的指向一个对象,而不会影响对象的引用计数。而SoftReference更特别,在内存足够时,对象会因为SoftReference的存在而不被收集,但内存不足时,对象就还是会被收集。代码如下:
Foo foo = new Foo();
SoftReference sr= new SoftReference(foo);
Foo bar = sr.get();
如果foo已被垃圾收集,sr.get()会返回null;
另外还有一个ReferenceQueue的机制,使得对象被回收时能获得通知,比finalize()完全不知道GC何时会执行要聪明的多。
ReferenceQueue rq = new ReferenceQueue();
ref = new WeakReference(foo, rq);
WeakReference cleaned = rq.pool();
cleaned就是刚刚被GC掉的WeakReference。

没有评论: