简体   繁体   English

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

[英]java -> System.gc(); Does this call opens a new Thread or not?

For example I such a code 例如我这样的代码

... get some memory and lose all the pointers to that memory so that System.gc(); ...获得一些内存并丢失指向该内存的所有指针,因此System.gc(); can collect it. 可以收集它。

call System.gc(); 调用System.gc();

do some other tasks; 做一些其他任务;


Here does the "do some other tasks;" 在此执行“其他任务”; and "System.gc();" 和“ System.gc();” works in paralel or does the "do some other tasks;" 并行工作或“执行其他任务”; waits for "System.gc();" 等待“ System.gc();” to be executed 被执行

Thank you 谢谢

You probably shouldn't be using System.gc(). 您可能不应该使用System.gc()。 A common misconception with C/C++ users coming over to java is they think they need to tell the virtual machine when it can perform garbage collection. 对于使用Java的C / C ++用户,一个普遍的误解是他们认为他们需要告诉虚拟机何时可以执行垃圾回收。 The reality is that the garbage collector is highly optimized and performs this task by itself when it feels it is best to do so. 现实情况是,垃圾收集器经过了高度优化,并且在感觉最好的时候可以自行执行此任务。 Calling System.gc() is not usually recommended. 通常不建议调用System.gc()。

If you do call System.gc() though, it will 'recommend' to the system to perform garbage collection. 如果您确实调用System.gc(),它将“推荐”给系统执行垃圾回收。 It may not actually perform a collection though it usually does. 尽管通常会执行收集,但实际上可能不会执行收集。 If it runs in another thread depends on the actual collection algorithm. 它是否在另一个线程中运行取决于实际的收集算法。 The default one will block everything while it runs. 默认值将在运行时阻止所有内容。 So it may run in separate threads but it will block your current execution when it does. 因此它可能在单独的线程中运行,但是在执行时会阻止您当前的执行。

The exact behavior here depends entirely on the JVM implementation. 这里的确切行为完全取决于JVM实现。 In spec (that is what a proper JVM implementation needs to provide you), it can happen in parallel, it can happen first before your code executes, or it can not happen at all. 在规范中(这是适当的JVM实现需要为您提供的功能),它可以并行发生,可以在代码执行之前首先发生,或者根本不发生。

In practice, my observation on JVMs I have happened to observe is that it runs immediately in a separate thread. 在实践中,我对偶然发现的JVM的观察是,它立即在单独的线程中运行。 However, in some cases multiple calls spawn multiple threads, sometimes it queues the requests on one thread. 但是,在某些情况下,多个调用会产生多个线程,有时它会将请求排队在一个线程上。 The Garbage collection launched was always a "stop-the-world" type (that is it was very complete and slowed or paused the application). 启动的垃圾回收始终是“世界停止”类型(也就是说,它非常完整,会减慢或暂停应用程序)。

However, given your comment to @Chris Dail, your underlying problem isn't the behavior of a System.gc() call. 但是,考虑到您对@Chris Dail的评论,您的根本问题不是System.gc()调用的行为。 Calling System.gc() can have some uses. 调用System.gc()可以有一些用途。 It can be used clear memory so you can get a sense of how large the footprint of the application actually is currently. 可以使用它来清除内存,以便您可以大致了解当前应用程序实际占用的空间。 It can also be used as a strategy to ensure that a stop-the-world garbage collection happens earlier so that it "stops the world" for a shorter amount of time because there is less memory to clear. 它也可以用作一种策略,以确保尽早进行“世界停止”垃圾回收,从而可以在更短的时间内“停止世界”,因为需要清除的内存更少。 (I should note that as JVM's get more and more sophisticated this kind of thing is less and less necessary, and actually becomes counter-productive). (我应该注意,随着JVM变得越来越复杂,这种事情变得越来越少,并且实际上适得其反)。

What it does not do however, is in any way solve an OutOfMemoryError. 但是,它不能以任何方式解决OutOfMemoryError。 The JVM will not give you an OutOfMemoryError until it has garbage collected to the best of its ability. JVM会尽力收集垃圾之前不会给您OutOfMemoryError。 Calling System.gc does not change that. 调用System.gc不会改变它。 If you have an OutOfMemoryError it is likely because you are holding reference to objects in ways that you don't really need, but that are preventing those Objects memory from being reclaimed. 如果您有OutOfMemoryError,则可能是因为您以不需要的方式持有对对象的引用,但是这阻止了这些Objects内存的回收。

It's usually synchronous, but not guaranteed. 它通常是同步的,但不能保证。

Actually is neither guaranteed that a collection will effectively take place since the JVM will decide if it makes sense and what kind of garbage collection use. 实际上,这两种方法都不能保证有效地进行收集,因为JVM会决定是否有意义以及使用哪种垃圾收集。

If you need additional info you can launch your program with -verbosegc flag.. 如果需要其他信息,可以使用-verbosegc标志启动程序。

In any case the garbage collection is something that it issued automatically by the JVM without any specified calls, invoking System.gc() is just a hint you give to let it know that it may start a collection. 在任何情况下,垃圾回收都是由JVM自动发出的,没有任何指定的调用,调用System.gc()只是一个提示,使您知道它可以启动回收。

How the Garbage collection is executed is up to the JVM-implementation. 垃圾回收的执行方式取决于JVM的实现。 Usual implementations may stop all threads, to collect memory globally, stop only one thread to collect memory local for this thread for instance. 通常的实现可能会停止所有线程,以全局方式收集内存,例如,仅停止一个线程以收集该线程本地的内存。 Read more about garbage collection from Sun and in this older but good article . 在这篇较旧但不错的文章中,可以了解更多有关Sun垃圾收集的信息。

As Eric Eijkelenboom pointed out, calling this method does not mean the the Garbage Collector will execute immediately. 正如Eric Eijkelenboom指出的那样,调用此方法并不意味着垃圾回收器将立即执行。 Actually you don't know if it will be called at all... 实际上,您根本不知道是否会调用它...

In your case (judging from the comment on Amarghosh 's answer) you need to free up some memory before you do something that requires a lot of RAM am i right? 在您的情况下(从对Amarghosh答案的评论中判断),您需要在执行需要大量RAM的操作之前释放一些内存,对吗? In that case you don't need to worry. 在这种情况下,您无需担心。 If there is enough memory to be garbage collected it will be done automatically when you try to allocate it. 如果有足够的内存可以进行垃圾回收,则在尝试分配内存时将自动完成。

“执行其他任务”等待System.gc()执行并返回。

There is no way to know. 没有办法知道。 Calling System.gc() does not mean that a garbage collection is performed at that very second, it is merely scheduled. 调用System.gc()并不意味着在那一秒执行垃圾回收,它只是调度的。 It is up to the JVM to perform the garbage collection at a suitabe time. 由JVM决定是否在适当的时候执行垃圾回收。

the javadoc tells http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#gc() : " When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects. " javadoc告诉http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#gc() :“ 当控件从方法调用返回时,Java虚拟机已经完成尽最大努力从所有丢弃的物体中回收空间。

So I would say that "do some other tasks;" 所以我会说“做一些其他任务”; waits for "System.gc();" 等待“ System.gc();” to be executed! 被执行!

No parallelism is used - and that's not good for a Java application. 没有使用并行性-这对于Java应用程序来说不是很好。 In fact, it's never a good idea to call/force the Garbage Collector. 实际上,调用/强制垃圾收集器绝不是一个好主意。 It must be reserve to extreme cases with no other solutions... 它必须保留给极端情况,没有其他解决方案...

Bye, Alban. 再见,奥尔本。

According to the Java specification, the thread which calls System.gc() is stopped until the GC has done its deed. 根据Java规范, 调用 System.gc()的线程将停止运行,直到GC完成其任务为止。 Note that this is just a hint, the JVM is free to ignore it, and Sun's JVM actually has a command-line switch ( -XX:-DisableExplicitGC ) to that effect. 请注意,这只是一个提示,JVM可以随意忽略它,Sun的JVM实际上有一个命令行开关( -XX:-DisableExplicitGC )可以达到这种效果。 With this switch, System.gc() does nothing and returns immediately. 使用此开关, System.gc()不会执行任何操作并立即返回。

Either way, nothing in the specification prevents other threads from running. 无论哪种方式,规范中都没有阻止其他线程运行的方法。 This depends on the GC algorithm; 这取决于GC算法。 Sun's JVM includes several, some of which being able to run concurrently with the applicative threads for most of their work. Sun的JVM包括多个,其中一些能够在大多数工作中与应用程序线程同时运行。

As was pointed out by others, the net effect of calling System.gc() explicitly is, most of the time, to decrease performance. 正如其他人指出的那样,在大多数情况下,显式调用System.gc()的最终结果是降低性能。 If you feel that you must call that method, then chances are that you are doing something wrong. 如果您认为必须调用该方法,则可能是您做错了什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM