7

I need a way to be able to trigger full GC from a linux console script on ubuntu. I know this is extremely bad practice but without going into too much detail this keeps my server running, This is only meant for 1 or 2 days while I fix the actual problem, so I don't have to wake up in the night and perform manual GC through jconsole or jvisualvm.

Alternatively I have to make a mouse script that clicks the button every 3-4 hours or so which is even worse.

Please help.

Ævar Örn Kvaran
  • 115
  • 1
  • 1
  • 5

4 Answers4

11

If you can have your application start a JMX server (which I believe is implied from your use of jconsole/jvisualvm), then you can invoke the Memory MBean's gc operation via command-line utilities.

Firstly you'll need some kind of command-line JMX client. I've used this one in the past for simple command-line invocations and it worked fine. (Edit: In fact I used it just now to test out the following command, and it invoked GC successfully on a local Tomcat process)

Then you'll need to work out the command to trigger garbage collection. I think this should work (you'll of course need to change hosts/ports/credentials as appropriate):

java -jar cmdline-jmxclient-X.X.jar - localhost:8081 java.lang:type=Memory gc

Finally, you can schedule invocation of this command via cron or equivalent.

Voila!

Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
  • 2
    This will work. It's a bit frightening that you need to do this, but it will work. – Mike Miller Nov 11 '10 at 15:14
  • +1 to that comment, though from the question I get the feeling that Ævar is already aware of that, and is using this technique as a stopgap fix. – Andrzej Doyle Nov 11 '10 at 15:24
  • Thank you very much , I tried and it worked, will save the night, although I am very close on fixing the actual problem. To clarify the problem a bit I have studied GC settings for a while now, and have done a lot of tuning. The problem is not that the JVM is running out of memory and the server actually works fine, but it is leaking CLOSE_WAIT sockets, which only get cleaned up during full GC. Which is also very strange, this fills up connection pools and file descriptor limits, and ends on hanging the server. – Ævar Örn Kvaran Nov 11 '10 at 15:34
  • 1
    Jconsole and jvisualvm dó not require JMX for local connections – Thorbjørn Ravn Andersen Nov 11 '10 at 16:26
  • 1
    If you have lingering waits you have something ELSE not doing TCP/IP xloses correctly. – Thorbjørn Ravn Andersen Nov 11 '10 at 16:28
  • @Thorbjørn - I believe they *do* require JMX, it's just that from Java 6 onwards, JMX is enabled locally by default for all processes. – Andrzej Doyle Nov 11 '10 at 17:42
  • @Andrzej, the attachment mechanism on a local machine in Java 6 do not use JMX. – Thorbjørn Ravn Andersen Nov 11 '10 at 18:02
8

If you have oracle jvm 1.7, you can use jcmd to list the jvm PIDs, and then jcmd <pid> GC.run to GC.

jcmd <pid> help will show you what other commands are available.

arya
  • 946
  • 5
  • 14
4
jcmd <pid> GC.run

Example:

jcmd 20350 GC.run
helder.vasc
  • 847
  • 8
  • 8
-2

It's not bad practice, it is impossible - even for the java application being executed by the JVM. There is a gc() call available but even it is only a hint to the JVM to run garbage collection. From the console, there is normally no way to influence the JVM while it is running.

Some has asked this question for the Windows platform, see question How to request JVM garbage collection (not from code) when run from Windows command-line

You might check out the JVM arguments for stack/heap sizes (both min and max). There are lots of tweaks you can do in that area but they are mostly specific to the JVM you are using.

JVM performance tuning for large applications

Community
  • 1
  • 1
Kelly S. French
  • 12,198
  • 10
  • 63
  • 93