System.gc()有什么意义?

jvm有自己的gc策略,那么我用System.gc()还有什么意义?

阅读 6.3k
2 个回答

主动提示回收内存

设想这样一个场景
你有100M 内存, 每次操作需要60M, 每一次操作完成后,系统有40M,jvm 不会去主动回收, 但紧接着第二次操作再申请60M 则会 OOM, 如果在第一次操作完成后 System.gc()一次,则系统可以正常动行.

伪码如下:

void bigmemop(){
    for(int i=0; i<100; i++){
      use60M();
      System.gc();
    }
}

一个项目里处理大的 Excel 表时恰好遇到这种情况. 当内存受限(什么时候不受限呢?)时, 主动控制还是很重要的.

PS:
代码依赖于 Gc 显然不是合理的, 因为 gc 可能什么都不做. 如果你不知道该不该用的时候,答案是:不要用!
但不是所有 jvm 都很聪明, 也不是所有 jvm 的默认行为都一致. 当没有更好的办法处理内存回收问题时, System.gc 为你提供了一个选择和可能性.

很多项目都有使用:
squirrel-sql-git, eclipse-jetty,
jmbr3d/MeshBrowser.java

大致可归结为以下场景:

  • 长时间运行的程序,如服务器,容器
  • 监控内存使用情况,为得到更真实数据
  • 允许用户手动干预
  • 短暂地大量创建对象,然后抛弃

UPDATE2:
我的项目里用 gc是近10年前, 用的是 JDK 1.5. 情况也远比上面的例子复杂, 为不至于误导大家, 先标记一下.

所以很少用。反正我是从来没用过。

------- 不同意楼下的回答。

为了确认我的判断的正确性,我特意去查了一些资料,而在我所查阅的资料里面,都没有说过“调用System.gc()可以防止OOM”。

JDK文档上对System.gc()的描述是:

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse.

注意用的是“suggests”,而不是“make”。

另外还有SO上的这篇问答:https://stackoverflow.com/que...

其中的所有答案几乎都提到了System.gc()仅仅只是“建议”做垃圾回收,而不是“一定”会做垃圾回收。

而且得票最高的答案明确说了一句话:

If the JVM is about to throw an OutOfMemoryError, calling System.gc() won't stop it

所以,@Yujiaao ,我期待你的示例能够做到:加上System.gc()就不会OOM,不加就会OOM的效果

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题