셸에서 가비지 수집을 어떻게 강제합니까?


106

그래서 원격 상자에 jmap이있는 힙을보고 있으며 가비지 수집을 강제하고 싶습니다. jvisualvm 또는 jconsole 및 친구에 들어 가지 않고 어떻게 할 수 있습니까?

나는 당신이 가비지 콜렉션을 강요해서는 안된다는 것을 안다. 힙이 왜 커지거나 커지는 지 알아 내야한다.

또한 System.GC ()가 실제로 가비지 수집을 강제하지 않는다는 것을 알고 있습니다. 단지 GC에 발생하기를 원한다는 것을 알려줍니다.

이것을 쉽게 할 수있는 방법이 있다고 말했습니까? 누락 된 명령 줄 앱이 있습니까?


답변:


25

무료 jmxterm 프로그램을 통해이 작업을 수행 할 수 있습니다 .

다음과 같이 실행하십시오.

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

여기에서 호스트에 연결하고 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

bash / perl / ruby ​​/ other 스크립트에이를 포함하는 방법에 대한 정보는 jmxterm 웹 사이트의 문서를 참조하십시오. 이 작업을 수행하기 위해 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

346

JDK 7부터 다음과 같은 JDK 명령 도구 'jcmd'를 사용할 수 있습니다.

jcmd <pid> GC.run


22
왜 당신들은 이런 것들에 대해 말하지 않습니까?! :)
noahlz 2014 년

2
당신이 "AttachNotSupportedException : 열려있는 소켓 파일에 없습니다"를 얻을 경우, 볼 이 답변에 내 추가
토마스 Rebele

그리고 당신이 얻는다면 VM 인수 Explicit GC is disabled, no GC has been performed때문일 수 있습니다 -XX:+DisableExplicitGC. 참조 : mail.openjdk.java.net/pipermail/serviceability-dev/2017-August/…
Eyal Roth

이것은 Oracle JDK에서만 작동하며 open-jdk에서는 작동하지 않습니다.
Ali Saleh

104

를 실행 jmap -histo:live <pid>하면 아무것도 출력하기 전에 힙에 전체 GC가 강제 실행 됩니다.


3
모든 자바에서 가비지 컬렉션을 강제 실행합니다. ps axf | grep 자바 | grep -v grep | awk '{print "jmap -histo : live"$ 1}'| sh
gtrak

1
어디에 문서화되어 있습니까? : live 없이는 어떻습니까 (예 : -F가 필요할 때)?
nafg

7
2014 년의 신비한 미래에서 안녕하세요. jcmd이제 작업에 적합한 도구입니다.
noahlz 2014 년

16

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
...

이것은 이 stackoverflow 답변의 도움으로 해결할 수 있습니다.

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

<process_owner>PID로 프로세스를 실행하는 사용자는 어디에 있습니까 <pid>? 둘 다 top또는htop


다음은 어떻습니까? 같은 것? java.io.IOException: Operation not permitted
dhockey

아직이 오류 메시지가 표시되지 않았습니다. 와 함께 작동 sudo -u <process_owner> jcmd <pid> GC.run할 수 있습니다. 시도해 볼 수 있습니까? 이 명령은 안전합니다
토마스 Rebele

나는 가지고 있었지만 그 컴퓨터에 sudo 액세스 권한이 없습니다.
dhockey

도구가 올바르게 작동합니다. 운영 체제에서 실행할 권한이 없습니다. Java를 사용하지 않더라도 다른 응용 프로그램에도 동일하게 적용됩니다.
aled

6

몇 가지 다른 솔루션이 있습니다 (이미 여기에 좋은 솔루션이 많이 있습니다).

다음 예는 cmdline-jmxclient에 대한 것입니다.

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

이것은 한 줄 뿐이고 스크립트에 정말 쉽게 넣을 수 있기 때문에 좋습니다.


5

Linux의 경우 :

$ jcmd $(pgrep java) GC.run

jcmdJDK와 함께 패키지화되어 $(pgrep java)Java의 프로세스 ID를 가져옵니다.


이것은 하나의 Java 프로세스가 실행중인 경우에만 작동합니다. 그렇지 않으면 두 번째 PID를 jcmd에 대한 명령으로 해석하여 분명히 인식되지 않고 오류가 발생합니다.
Cas Eliëns

0

동일한 명령 줄 옵션이 없다고 생각합니다.

동일한 경우 jvisualvm / jconsole을 사용해야합니다.

이 도구를 사용하여 프로그램의 메모리가 높은 이유를 확인하는 것이 좋습니다.

어쨌든 GC를 강요해서는 안됩니다. GC 알고리즘을 방해하고 프로그램을 느리게 만들 수 있기 때문입니다.


0

애플리케이션과 함께 jolokia 를 사용하는 경우 다음 명령을 사용하여 가비지 컬렉션을 트리거 할 수 있습니다.

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

-10

다만:

kill -SIGQUIT <PID>

4
이것은 가비지 콜렉션이 아닌 힙 덤프를 트리거합니다
Dror Bereznitsky

적어도 솔라리스는 힘 GC를 수행합니다.
Amin Abbaspour 2014

2
Solaris에서도 SIGQUIT는 GC 또는 힙 덤프를 트리거하지 않습니다. SIGQUIT는 HotSpot에 대해서만 스레드 덤프를 트리거합니다. IBM JVM의 경우 구성 가능합니다.
Mircea Vutcovici

GC를 트리거하지 않고 스택 추적 만 인쇄합니다.
Elad Tabak
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.