Java 如何强制从 Shell 收集垃圾?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3523837/
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
How do you Force Garbage Collection from the Shell?
提问by eyberg
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?
因此,我正在远程设备上查看带有 jmap 的堆,并且想对其强制进行垃圾回收。您如何在不进入 jvisualvm 或 jconsole 和朋友的情况下执行此操作?
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.
我也意识到 System.GC() 实际上并不强制垃圾收集——它只是告诉 GC 你希望它发生。
Having said that is there a way to do this easily? Some command line app I'm missing?
话虽如此,有没有办法轻松做到这一点?我缺少一些命令行应用程序?
采纳答案by Harold L
You can do this via the free jmxtermprogram.
Fire it up like so:
像这样启动它:
java -jar jmxterm-1.0-alpha-4-uber.jar
From there, you can connect to a host and trigger GC:
从那里,您可以连接到主机并触发 GC:
$>open host:jmxport
#Connection to host:jmxport is opened
$>bean java.lang:type=Memory
#bean is set to java.lang:type=Memory
$>run gc
#calling operation gc of mbean java.lang:type=Memory
#operation returns:
null
$>quit
#bye
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.
查看 jmxterm 网站上的文档,了解有关将其嵌入 bash/perl/ruby/other 脚本的信息。我已经使用 Python 中的 popen2 或 Perl 中的 open3 来做到这一点。
UPDATE:here's a one-liner using jmxterm:
更新:这是一个使用 jmxterm 的单行:
echo run -b java.lang:type=Memory gc | java -jar jmxterm-1.0-alpha-4-uber.jar -n -l host:port
回答by YoK
I don't think there is any command line option for same.
我不认为有任何相同的命令行选项。
You will need to use jvisualvm/jconsole for same.
您将需要使用 jvisualvm/jconsole。
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.
无论如何,您不应该强制 GC,因为它肯定会干扰 GC 算法并使您的程序变慢。
回答by The Alchemist
There's a few other solutions (lots of good ones here already):
还有一些其他解决方案(这里已经有很多好的解决方案):
- Write a little code to access the MemoryMBeanand call
gc()
. - Using a command-line JMX client (like cmdline-jmxclient, jxmterm) and run the
gc()
operation on the MemoryMBean
- 编写一些代码来访问MemoryMBean并调用
gc()
. - 使用命令行 JMX 客户端(如cmdline-jmxclient、jxmterm)并
gc()
在 MemoryMBean 上运行操作
The following example is for the cmdline-jmxclient:
以下示例适用于 cmdline-jmxclient:
$ java -jar cmdline-jmxclient-0.10.3.jar - localhost:3812 'java.lang:type=Memory' gc
This is nice because it's only one line and you can put it in a script really easily.
这很好,因为它只有一行,而且您可以非常轻松地将其放入脚本中。
回答by Will Hartung
If you run jmap -histo:live <pid>
, that will force a full GC on the heap before it prints anything out.
如果您运行jmap -histo:live <pid>
,这将在打印任何内容之前在堆上强制执行完整的 GC。
回答by Amin Abbaspour
just:
只是:
kill -SIGQUIT <PID>
回答by user3198490
Since JDK 7 you can use the JDK command tool 'jcmd' such as:
从 JDK 7 开始,您可以使用 JDK 命令工具“jcmd”,例如:
jcmd <pid> GC.run
jcmd <pid> GC.run
回答by dustmachine
回答by Thomas Rebele
Addition to user3198490's answer. Running this command might give you the following error message:
除了user3198490的回答。运行此命令可能会给您以下错误消息:
$ jcmd 1805 GC.run
[16:08:01]
1805:
com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
...
This can be solved with help of this stackoverflow answer
这可以在这个stackoverflow answer的帮助下解决
sudo -u <process_owner> jcmd <pid> GC.run
where <process_owner>
is the user that runs the process with PID <pid>
. You can get both from top
or htop
<process_owner>
使用 PID 运行进程的用户在哪里<pid>
。您可以从top
或htop
回答by Xuejun Liu
for linux:
对于Linux:
$ jcmd $(pgrep java) GC.run
jcmd
is packaged with the JDK, $(pgrep java)
gets the process ID of java
jcmd
与JDK打包,$(pgrep java)
获取java的进程ID