Java System.gc() 什么时候做某事?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/66540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When does System.gc() do something?
提问by
I know that garbage collection is automated in Java. But I understood that if you call System.gc()
in your code that the JVM may or may not decide to perform garbage collection at that point. How does this work precisely? On what basis/parameters exactly does the JVM decide to do (or not do) a GC when it sees System.gc()
?
我知道垃圾收集在 Java 中是自动化的。但我明白,如果你调用System.gc()
你的代码,JVM 可能会或可能不会决定在那时执行垃圾收集。这是如何精确工作的?JVM 在看到 GC 时究竟根据什么基础/参数决定执行(或不执行)GC System.gc()
?
Are there any examples in which case it's a good idea to put this in your code?
是否有任何示例在这种情况下将其放入代码中是个好主意?
回答by jodonnell
In practice, it usuallydecides to do a garbage collection. The answer varies depending on lots of factors, like which JVM you're running on, which mode it's in, and which garbage collection algorithm it's using.
在实践中,它通常决定进行垃圾收集。答案因许多因素而异,例如您正在运行的 JVM、它处于哪种模式以及它使用的垃圾收集算法。
I wouldn't depend on it in your code. If the JVM is about to throw an OutOfMemoryError, calling System.gc() won't stop it, because the garbage collector will attempt to free as much as it can before it goes to that extreme. The only time I've seen it used in practice is in IDEs where it's attached to a button that a user can click, but even there it's not terribly useful.
我不会在你的代码中依赖它。如果 JVM 即将抛出 OutOfMemoryError,调用 System.gc() 不会阻止它,因为垃圾收集器将尝试在它达到极限之前尽可能多地释放它。我唯一一次在实践中看到它使用它是在 IDE 中,它附加到用户可以单击的按钮上,但即使在那里它也不是非常有用。
回答by Patrick
System.gc()
is implemented by the VM, and what it does is implementation specific. The implementer could simply return and do nothing, for instance.
System.gc()
由 VM 实现,它的作用是特定于实现的。例如,实现者可以简单地返回并且什么都不做。
As for when to issue a manual collect, the only time when you may want to do this is when you abandon a large collection containing loads of smaller collections--a
Map<String,<LinkedList>>
for instance--and you want to try and take the perf hit then and there, but for the most part, you shouldn't worry about it. The GC knows better than you--sadly--most of the time.
至于何时发布手动收集,您可能想要这样做的唯一时间是当您放弃包含大量较小集合的大型集合时 -
Map<String,<LinkedList>>
例如 - 然后您想尝试获得性能命中并且在那里,但在大多数情况下,您不必担心。GC 比你更清楚——遗憾的是——大多数时候。
回答by DustinB
You have no control over GC in java -- the VM decides. I've never run across a case where System.gc()
is needed. Since a System.gc()
call simply SUGGESTS that the VM do a garbage collection and it also does a FULL garbage collection (old and new generations in a multi-generational heap), then it can actually cause MOREcpu cycles to be consumed than necessary.
您无法控制 Java 中的 GC——由 VM 决定。我从来没有穿过其中的情况下运行System.gc()
的需要。由于System.gc()
调用简单地建议 VM 进行垃圾收集并且它还进行完整的垃圾收集(多代堆中的旧代和新代),因此它实际上可能导致消耗比必要更多的cpu 周期。
In some cases, it may make sense to suggest to the VM that it do a full collection NOW as you may know the application will be sitting idle for the next few minutes before heavy lifting occurs. For example, right after the initialization of a lot of temporary object during application startup (i.e., I just cached a TON of info, and I know I won't be getting much activity for a minute or so). Think of an IDE such as eclipse starting up -- it does a lot to initialize, so perhaps immediately after initialization it makes sense to do a full gc at that point.
在某些情况下,建议 VM 立即进行完整收集可能是有意义的,因为您可能知道应用程序将在接下来的几分钟内闲置,然后再进行繁重的工作。例如,在应用程序启动期间初始化大量临时对象之后(即,我刚刚缓存了大量信息,并且我知道我在一分钟左右的时间内不会获得太多活动)。想想一个 IDE,比如 eclipse 启动——它做了很多初始化工作,所以也许在初始化之后立即执行完整的 gc 是有意义的。
回答by zxcv
I can't think of a specific example when it is good to run explicit GC.
当运行显式 GC 时,我想不出一个具体的例子。
In general, running explicit GC can actually cause more harm than good, because an explicit gc will trigger a full collection, which takes significantly longer as it goes through every object. If this explicit gc ends up being called repeatedly it could easily lead to a slow application as a lot of time is spent running full GCs.
一般来说,运行显式 GC 实际上弊大于利,因为显式 gc 将触发完整收集,这在遍历每个对象时花费的时间要长得多。如果这个显式 gc 最终被重复调用,它很容易导致应用程序变慢,因为运行完整 GC 花费了大量时间。
Alternatively if going over the heap with a heap analyzer and you suspect a library component to be calling explicit GC's you can turn it off adding: gc=-XX:+DisableExplicitGC to the JVM parameters.
或者,如果使用堆分析器检查堆并且您怀疑某个库组件正在调用显式 GC,则可以将其关闭,在 JVM 参数中添加:gc=-XX:+DisableExplicitGC。
回答by David Schlosnagle
You need to be very careful if you call System.gc()
. Calling it can add unnecessary performance issues to your application, and it is not guaranteed to actually perform a collection. It is actually possible to disable explicit System.gc()
via the java argument -XX:+DisableExplicitGC
.
如果你打电话,你需要非常小心System.gc()
。调用它会给您的应用程序增加不必要的性能问题,并且不能保证实际执行集合。实际上可以System.gc()
通过 java 参数禁用显式-XX:+DisableExplicitGC
。
I'd highly recommend reading through the documents available at Java HotSpot Garbage Collectionfor more in depth details about garbage collection.
我强烈建议通读Java HotSpot Garbage Collection 中提供的文档,以了解有关垃圾收集的更多详细信息。
回答by Guillermo Vasconcelos
The only example I can think of where it makes sense to call System.gc() is when profiling an application to search for possible memory leaks. I believe the profilers call this method just before taking a memory snapshot.
我能想到的唯一一个例子是调用 System.gc() 是在分析应用程序以搜索可能的内存泄漏时。我相信分析器会在获取内存快照之前调用此方法。
回答by eckes
Most JVMs will kick off a GC (depending on the -XX:DiableExplicitGC and -XX:+ExplicitGCInvokesConcurrent switch). But the specification is just less well defined in order to allow better implementations later on.
大多数 JVM 将启动 GC(取决于 -XX:DiableExplicitGC 和 -XX:+ExplicitGCInvokesConcurrent 开关)。但是为了允许以后更好的实现,规范的定义不太明确。
The spec needs clarification: Bug #6668279: (spec) System.gc() should indicate that we don't recommend use and don't guarantee behaviour
规范需要澄清:Bug #6668279: (spec) System.gc() 应该表明我们不推荐使用并且不保证行为
Internally the gc method is used by RMI and NIO, and they require synchronous execution, which: this is currently in discussion:
RMI 和 NIO 在内部使用 gc 方法,它们需要同步执行,这:目前正在讨论中:
Bug #5025281: Allow System.gc() to trigger concurrent (not stop-the-world) full collections
回答by eckes
Normally, the VM would do a garbage collection automatically before throwing an OutOfMemoryException, so adding an explicit call shouldn't help except in that it perhaps moves the performance hit to an earlier moment in time.
通常,VM 会在抛出 OutOfMemoryException 之前自动执行垃圾收集,因此添加显式调用应该无济于事,除非它可能将性能影响移到更早的时间。
However, I think I encountered a case where it might be relevant. I'm not sure though, as I have yet to test whether it has any effect:
但是,我想我遇到了一个可能相关的案例。我不确定,因为我还没有测试它是否有任何影响:
When you memory-map a file, I believe the map() call throws an IOException when a large enough block of memory is not available. A garbage collection just before the map() file might help prevent that, I think. What do you think?
当您对文件进行内存映射时,我相信 map() 调用会在足够大的内存块不可用时引发 IOException。我认为,在 map() 文件之前进行垃圾收集可能有助于防止这种情况发生。你怎么认为?
回答by Peter Lawrey
If you use direct memory buffers, the JVM doesn't run the GC for you even if you are running low on direct memory.
如果您使用直接内存缓冲区,即使您的直接内存不足,JVM 也不会为您运行 GC。
If you call ByteBuffer.allocateDirect()
and you get an OutOfMemoryError you can find this call is fine after triggering a GC manually.
如果您调用ByteBuffer.allocateDirect()
并收到 OutOfMemoryError 错误,您会发现在手动触发 GC 后此调用是正常的。
回答by lwpro2
we can never force garbage collection. System.gc is only suggesting vm for garbage collection, however, really what time the mechanism runs, nobody knows, this is as stated by JSR specifications.
我们永远不能强制垃圾收集。System.gc 只是建议使用 vm 进行垃圾收集,但是,该机制究竟何时运行,没有人知道,这是 JSR 规范中规定的。