如何从 Shell 强制进行垃圾收集?

发布于 2024-09-15 15:29:35 字数 233 浏览 7 评论 0原文

因此,我正在查看远程机器上带有 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

箜明 2024-09-22 15:29:36

如果您在应用程序中使用 jolokia ,则可以使用以下命令触发垃圾收集:

curl http://localhost:8558/jolokia/exec/java.lang:type=Memory/gc

If you are using jolokia with your application, you can trigger a garbage collection with this command:

curl http://localhost:8558/jolokia/exec/java.lang:type=Memory/gc
养猫人 2024-09-22 15:29:36

考虑将 GNU 并行与 jcmd 结合使用,如下所示用于多个进程;

并行 'jcmd {} GC.run' ::: $(pgrep java)

Consider using GNU parallel with jcmd as below for multiple processes;

parallel 'jcmd {} GC.run' ::: $(pgrep java)

极度宠爱 2024-09-22 15:29:36

另外:

  • 要对具有相同应用程序、jar 文件等的多进程运行 GC。 使用:
jcmd your_application.jar GC.run
  • 要在 Windows 上运行 GC,请尝试:
cd C:\"Program Files"\Java\jdk-13.0.2\bin
.\jcmd.exe your_application.jar GC.run
  • MacOS / Linux:
jcmd your_application.jar GC.run
# or
/usr/bin/jcmd your_application.jar GC.run

In addition:

  • To run GC for multi process with the same application, jar file, etc. Use:
jcmd your_application.jar GC.run
  • To run GC on windows, try:
cd C:\"Program Files"\Java\jdk-13.0.2\bin
.\jcmd.exe your_application.jar GC.run
  • MacOS / Linux:
jcmd your_application.jar GC.run
# or
/usr/bin/jcmd your_application.jar GC.run
青衫儰鉨ミ守葔 2024-09-22 15:29:36

只是:

kill -SIGQUIT <PID>

just:

kill -SIGQUIT <PID>
送君千里 2024-09-22 15:29:35

从 JDK 7 开始,您可以使用 JDK 命令工具“jcmd”,例如:

jcmd; GC.运行

Since JDK 7 you can use the JDK command tool 'jcmd' such as:

jcmd <pid> GC.run

剑心龙吟 2024-09-22 15:29:35

如果您运行 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.

苏别ゝ 2024-09-22 15:29:35

您可以通过免费的 jmxterm 程序来完成此操作。

像这样启动它:

java -jar jmxterm-1.0-alpha-4-uber.jar

从那里,您可以连接到主机并触发 GC:

gt;open host:jmxport
#Connection to host:jmxport is opened
gt;bean java.lang:type=Memory
#bean is set to java.lang:type=Memory
gt;run gc
#calling operation gc of mbean java.lang:type=Memory
#operation returns: 
null
gt;quit
#bye

查看 jmxterm 网站上的文档,了解有关将其嵌入到 bash/perl/ruby/其他脚本中的信息。我在 Python 中使用 popen2 或在 Perl 中使用 open3 来执行此操作。

更新:这是使用 jmxterm 的一行:

echo run -b java.lang:type=Memory gc | java -jar jmxterm-1.0-alpha-4-uber.jar -n -l host:port

You can do this via the free jmxterm program.

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:

gt;open host:jmxport
#Connection to host:jmxport is opened
gt;bean java.lang:type=Memory
#bean is set to java.lang:type=Memory
gt;run gc
#calling operation gc of mbean java.lang:type=Memory
#operation returns: 
null
gt;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.

UPDATE: here's a one-liner using jmxterm:

echo run -b java.lang:type=Memory gc | java -jar jmxterm-1.0-alpha-4-uber.jar -n -l host:port
友欢 2024-09-22 15:29:35

添加到 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 stackoverflow 答案 解决

sudo -u <process_owner> jcmd <pid> GC.run

,其中 < ;process_owner> 是运行具有 PID 的进程的用户。您可以从 tophtop 获取两者

Addition to user3198490's answer. Running this command might give you the following error message:

$ 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

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

戏剧牡丹亭 2024-09-22 15:29:35

对于linux:

$ jcmd $(pgrep java) GC.run

jcmd与JDK一起打包,$(pgrep java)获取java的进程ID

for linux:

$ jcmd $(pgrep java) GC.run

jcmd is packaged with the JDK, $(pgrep java) gets the process ID of java

凯凯我们等你回来 2024-09-22 15:29:35

还有一些其他解决方案(这里已经有很多好的解决方案):

以下示例适用于 cmdline -jmxclient:

$ java -jar cmdline-jmxclient-0.10.3.jar - localhost:3812 'java.lang:type=Memory' gc

这很好,因为它只有一行,您可以轻松地将其放入脚本中。

There's a few other solutions (lots of good ones here already):

The following example is for the 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.

小清晰的声音 2024-09-22 15:29:35

除了 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 calls java.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.

能怎样 2024-09-22 15:29:35

我认为没有任何命令行选项。

您将需要使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文