当前位置:  开发笔记 > 编程语言 > 正文

System.gc()什么时候做什么

如何解决《System.gc()什么时候做什么》经验,为你挑选了8个好方法。

我知道垃圾收集在Java中是自动化的.但我明白,如果你System.gc()在代码中编写,Java VM可能会或可能不会在运行时决定在那时进行垃圾收集.这是如何工作的?基于什么基础/参数,VM在看到GC时决定做(或不做)GC System.gc()?是否有可能的例子在这种情况下将它放在代码中个好主意?



1> jodonnell..:

在实践中,它通常决定进行垃圾收集.答案取决于很多因素,例如您正在运行的JVM,它所处的模式以及它正在使用的垃圾收集算法.

我不会在你的代码中依赖它.如果JVM即将抛出OutOfMemoryError,则调用System.gc()将不会停止它,因为垃圾收集器将在它进入极端之前尝试尽可能多地释放它.我在实践中看到它的唯一一次是在IDE中,它附加到用户可以点击的按钮,但即便如此,它也不是非常有用.


@bene你能真的"强迫"吗?jconsole刚刚调用System.gc()吗?
你可以在jconsole中强制进行垃圾收集
在视频游戏的加载屏幕中,我会使用“ System.gc()”。那时,我真的不在乎该呼叫是否清除了所有可能清除的内容,或者什么也不做。但是,我更希望*在加载屏幕上而不是在游戏过程中“花费更多精力回收未使用的对象”。

2> Guillermo Va..:

我能想到调用System.gc()的唯一例子是在分析应用程序以搜索可能的内存泄漏时.我相信分析器在获取内存快照之前调用此方法.


是的,这也是我的意思.Runtime.freeMemory()返回的值仅在System.gc()之后才有意义,因为通常您想知道无法收集的实例阻止了多少内存.当然只用于调试/内存分析,从不在生产中.

3> DustinB..:

你无法控制java中的GC - VM决定.我从来没有穿过其中的情况下运行System.gc()需要.由于System.gc()调用只是假设VM执行垃圾收集并且它还执行完全垃圾收集(多代堆中的新旧代),因此它实际上可能导致消耗超过必要的更多 cpu周期.

在某些情况下,向VM建议它现在进行完整收集可能是有意义的,因为您可能知道应用程序在繁重提升之前将在接下来的几分钟内处于空闲状态.例如,在应用程序启动期间初始化很多临时对象之后(即,我刚刚缓存了一大堆信息,我知道我将在一分钟左右没有获得太多活动).想象一下像eclipse这样的IDE启动 - 初始化它会做很多事情,所以也许在初始化之后立即执行一个完整的gc是有意义的.



4> Pierre Lapor..:

Java语言规范不保证JVM在您调用时将启动GC System.gc().这就是为什么"可能会或可能不会决定在那时做GC".

现在,如果您查看OpenJDK源代码(它是Oracle JVM的主干),您将看到调用System.gc()确实启动了GC循环.如果您使用其他JVM,例如J9,则必须检查其文档以找出答案.例如,Azul的JVM有一个连续运行的垃圾收集器,所以调用System.gc()不会做任何事情

其他一些答案提到在JConsole或VisualVM中启动GC.基本上,这些工具可以远程调用System.gc().

通常,您不希望从代码中启动垃圾回收周期,因为它会混淆应用程序的语义.你的应用程序做了一些业务,JVM负责内存管理.您应该将这些问题分开(不要让您的应用程序进行一些内存管理,专注于业务).

但是,很少有情况下System.gc()可以理解呼叫.例如,考虑微基准测试.没有人希望在微基准测试的中间发生GC循环.因此,您可以在每次测量之间触发GC循环,以确保每个测量都以空堆开始.



5> David Schlos..:

如果你打电话,你需要非常小心System.gc().调用它可能会给应用程序添加不必要的性能问题,并且无法保证实际执行集合.实际上可以System.gc()通过java参数禁用显式-XX:+DisableExplicitGC.

我强烈建议您阅读Java HotSpot垃圾收集中提供的文档,以获取有关垃圾收集的更多详细信息.


@Sagar Devanga按照您的描述手动调用gc不太可能有所帮助。在抛出OOM之前,JVM将已经尝试进行垃圾回收以释放内存。

6> Patrick..:

System.gc()由VM实现,它的功能是特定于实现.例如,实施者可以简单地返回并且什么都不做.

至于何时发布手动收集,只有当你放弃一个包含大量较小集合的大型集合时才会这样做 - Map> 例如 - 当你想要尝试接受性能指数时在那里,但在大多数情况下,你不应该担心它.GC比你更清楚 - 很遗憾 - 大多数时候.



7> Peter Lawrey..:

如果使用直接内存缓冲区,即使直接内存不足,JVM也不会为您运行GC.

如果您调用ByteBuffer.allocateDirect()并且得到OutOfMemoryError,则可以在手动触发GC后发现此调用正常.



8> eckes..:

大多数JVM将启动GC(取决于-XX:DiableExplicitGC和-XX:+ ExplicitGCInvokesConcurrent开关)。但是,规范的定义不太明确,以便以后可以更好地实现。

规范需要澄清:错误#6668279 :(规范)System.gc()应该表明我们不建议使用也不保证行为

RMI和NIO在内部使用gc方法,它们需要同步执行,这是当前正在讨论的问题:

错误#5025281:允许System.gc()触发并发(而不是世界末日)完整集合

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有