如何从 Shell 强制进行垃圾收集?
因此,我正在查看远程机器上带有 jmap 的堆,并且我想对其强制进行垃圾收集。如何在不弹出 jvisualvm 或 jconsole 之类的情况下执行此操作?
我知道你不应该进行强制垃圾收集的实践——你应该弄清楚为什么堆很大/不断增长。
我还意识到 System.GC() 实际上并不强制垃圾回收——它只是告诉 GC 您希望它发生。
话虽如此,有没有一种方法可以轻松做到这一点?我缺少一些命令行应用程序?
So I am looking at a heap with jmap on a remote box and I want to force garbage collection on it. How do you do this without popping into jvisualvm or jconsole and friends?
I know you shouldn't be in the practice of forcing garbage collection -- you should just figure out why the heap is big/growing.
I also realize the System.GC() doesn't actually force garbage collection -- it just tells the GC that you'd like it to occur.
Having said that is there a way to do this easily? Some command line app I'm missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
如果您在应用程序中使用 jolokia ,则可以使用以下命令触发垃圾收集:
If you are using jolokia with your application, you can trigger a garbage collection with this command:
考虑将 GNU 并行与 jcmd 结合使用,如下所示用于多个进程;
并行 'jcmd {} GC.run' ::: $(pgrep java)
Consider using GNU parallel with jcmd as below for multiple processes;
parallel 'jcmd {} GC.run' ::: $(pgrep java)
另外:
In addition:
只是:
just:
从 JDK 7 开始,您可以使用 JDK 命令工具“jcmd”,例如:
jcmd; GC.运行
Since JDK 7 you can use the JDK command tool 'jcmd' such as:
jcmd <pid> GC.run
如果您运行 jmap -histo:live,这将在打印任何内容之前强制在堆上进行完整 GC。
If you run
jmap -histo:live <pid>
, that will force a full GC on the heap before it prints anything out.您可以通过免费的 jmxterm 程序来完成此操作。
像这样启动它:
从那里,您可以连接到主机并触发 GC:
查看 jmxterm 网站上的文档,了解有关将其嵌入到 bash/perl/ruby/其他脚本中的信息。我在 Python 中使用 popen2 或在 Perl 中使用 open3 来执行此操作。
更新:这是使用 jmxterm 的一行:
You can do this via the free jmxterm program.
Fire it up like so:
From there, you can connect to a host and trigger GC:
Look at the docs on the jmxterm web site for information about embedding this in bash/perl/ruby/other scripts. I've used popen2 in Python or open3 in Perl to do this.
UPDATE: here's a one-liner using jmxterm:
添加到 user3198490 的答案。运行此命令可能会向您显示以下错误消息:
这可以通过 this stackoverflow 答案 解决
,其中
< ;process_owner>
是运行具有 PID
的进程的用户。您可以从top
或htop
获取两者Addition to user3198490's answer. Running this command might give you the following error message:
This can be solved with help of this stackoverflow answer
where
<process_owner>
is the user that runs the process with PID<pid>
. You can get both fromtop
orhtop
对于linux:
jcmd
与JDK一起打包,$(pgrep java)
获取java的进程IDfor linux:
jcmd
is packaged with the JDK,$(pgrep java)
gets the process ID of java还有一些其他解决方案(这里已经有很多好的解决方案):
gc()
。gc()
操作以下示例适用于 cmdline -jmxclient:
这很好,因为它只有一行,您可以轻松地将其放入脚本中。
There's a few other solutions (lots of good ones here already):
gc()
.gc()
operation on the MemoryMBeanThe following example is for the cmdline-jmxclient:
This is nice because it's only one line and you can put it in a script really easily.
除了 user3198490 的答案之外,如果运行
jcmd后没有任何变化, GC.run
,原因可能是:GC。 run
本质上是调用java.lang.System.gc()
,这只是gc的一个提示,JVM可以随意忽略它。如果您想确保强制执行完整 GC,可以选择使用:
jcmd; GC.heap_dump filename.hprof
该命令的最初目的是创建一个名为
filename.hprof
的堆转储文件。但作为副作用,为了到达所有活动对象,它“请求除非指定 -all 选项,否则将执行完整 GC”。还有一些其他命令,例如此答案中提到的
jmap -histo:live
以同样的方式触发 GC 作为副作用。In addition to user3198490's answer, if nothing really changes after you run
jcmd <pid> GC.run
, the reason could be:GC.run
essentially callsjava.lang.System.gc()
, which is just a hint to gc and the JVM is free to ignore it.If you want to ensure a full GC is FORCED, a choice is to use:
jcmd <pid> GC.heap_dump filename.hprof
The original purpose of this command is to create a heap dump file named
filename.hprof
. But as a side effect, in order to reach all the live objects, it "request a full GC unless the -all option is specified".There are some other commands like
jmap -histo:live <PID>
mentioned in this answer triggers GC as a side effect in the same way.我认为没有任何命令行选项。
您将需要使用 jvisualvm/jconsole 来实现相同目的。
我宁愿建议您使用这些工具来确定您的程序内存占用过高的原因。
无论如何你不应该强制GC,因为它肯定会扰乱GC算法并使你的程序变慢。
I don't think there is any command line option for same.
You will need to use jvisualvm/jconsole for same.
I would rather suggest you to use these tools to identity , why your program is high on memory.
Anyways you shouldn't force GC, as it would certainly disturb GC algorithm and make your program slow.