java->;gc();此调用是否打开新线程?

java->;gc();此调用是否打开新线程?,java,concurrency,garbage-collection,multithreading,sequential,Java,Concurrency,Garbage Collection,Multithreading,Sequential,例如,我需要这样的代码 。。。 获取一些内存并丢失所有指向该内存的指针,以便System.gc();我可以收集它 调用System.gc() 做一些其他的工作 这里的“do some other tasks;”和“System.gc();”并行工作,或者“do some other tasks;”等待执行“System.gc();” 谢谢。“执行其他任务”等待执行并返回。没有办法知道。调用System.gc()并不意味着垃圾收集就在那一秒执行,它只是被安排的。由JVM一次执行垃圾收集 您可能不

例如,我需要这样的代码

。。。 获取一些内存并丢失所有指向该内存的指针,以便System.gc();我可以收集它

调用System.gc()

做一些其他的工作


这里的“do some other tasks;”和“System.gc();”并行工作,或者“do some other tasks;”等待执行“System.gc();”


谢谢。

“执行其他任务”等待执行并返回。

没有办法知道。调用
System.gc()
并不意味着垃圾收集就在那一秒执行,它只是被安排的。由JVM一次执行垃圾收集

您可能不应该使用System.gc()。使用java的C/C++用户的一个常见误解是,他们认为需要告诉虚拟机何时可以执行垃圾收集。事实上,垃圾收集器是高度优化的,当它认为最好这样做时,它会自己执行这项任务。通常不建议调用System.gc()


但是,如果确实调用System.gc(),它将“建议”系统执行垃圾收集。虽然它通常会执行收集,但它实际上可能不会执行收集。它是否在另一个线程中运行取决于实际的收集算法。默认设置将在运行时阻止所有内容。因此,它可以在不同的线程中运行,但当它运行时会阻止当前的执行。

它通常是同步的,但不能保证

实际上,这两者都不能保证收集将有效地进行,因为JVM将决定它是否有意义以及使用何种垃圾收集

如果需要其他信息,可以使用
-verbosegc
标志启动程序


在任何情况下,垃圾收集都是由JVM在没有任何指定调用的情况下自动发出的,调用
System.gc()
只是一个提示,让它知道它可能开始收集。

垃圾收集的执行方式取决于JVM实现。通常的实现可能会停止所有线程,以全局收集内存,例如,只停止一个线程以收集该线程的本地内存。请阅读本书中有关垃圾收集的更多信息。

正如所指出的,调用此方法并不意味着垃圾收集器将立即执行。实际上你根本不知道它是否会被调用

在你的情况下(从评论的答案判断),你需要在做需要大量内存的事情之前释放一些内存,对吗?那样的话,你就不用担心了。如果有足够的内存进行垃圾回收,则在您尝试分配内存时会自动进行垃圾回收。

javadoc告诉: 当控件从方法调用返回时,Java虚拟机已尽最大努力从所有丢弃的对象中回收空间

所以我想说“做一些其他的任务;”等待“System.gc();”被执行

没有使用并行性——这对Java应用程序不好。事实上,调用/强制垃圾收集器从来都不是一个好主意。它必须保留到没有其他解决方案的极端情况下

再见,
Alban。

这里的确切行为完全取决于JVM实现。在规范中(这是一个适当的JVM实现需要提供给您的),它可以并行发生,可以在代码执行之前先发生,也可以根本不发生

在实践中,我对JVM的观察结果是,它立即在一个单独的线程中运行。但是,在某些情况下,多个调用会产生多个线程,有时它会在一个线程上对请求进行排队。启动的垃圾收集始终是“停止世界”类型(也就是说,它非常完整,并且减慢或暂停了应用程序)

然而,鉴于您对@Chris Dail的评论,您的根本问题不是System.gc()调用的行为。调用System.gc()可能有一些用途。它可以用于清除内存,这样您就可以了解当前应用程序的实际占用空间有多大。它还可以用作一种策略,以确保stop the world垃圾收集发生得更早,从而缩短“stop the world”的时间,因为要清除的内存更少。(我应该注意到,随着JVM变得越来越复杂,这种事情的必要性越来越低,实际上会适得其反)


然而,它并没有以任何方式解决OutOfMemory错误。JVM将不会给您一个OutOfMemoryError,直到它最大限度地收集了垃圾。调用System.gc不会改变这一点。如果您有OutOfMemoryError,可能是因为您以您并不真正需要的方式持有对对象的引用,但这会阻止这些对象的内存被回收。

根据Java规范,调用
System.gc()
的线程将停止,直到gc完成其操作。请注意,这只是一个提示,JVM可以随意忽略它,Sun的JVM实际上有一个命令行开关(
-XX:-DisableExplicitGC
)。使用此开关,
System.gc()
不执行任何操作并立即返回

无论哪种方式,规范中的任何内容都不会阻止其他线程运行。这取决于GC算法;Sun的JVM包括几个,其中一些能够在大部分工作中与应用程序线程并发运行


正如其他人所指出的,显式调用
System.gc()
的净效果通常是降低性能。如果您觉得必须调用该方法,那么很可能您做错了什么。

我希望您是正确的。因为我假设是这样,并据此编写了代码。确定吗?参见
System.gc()
的API文档中的“控制恢复时”