2010-08-19 36 views
68

Vì vậy, tôi đang nhìn vào một đống với jmap trên một hộp từ xa và tôi muốn lực lượng thu gom rác trên đó. Làm thế nào để bạn làm điều này mà không popping vào jvisualvm hoặc jconsole và bạn bè?Làm thế nào để bạn Force Garbage Collection khỏi Shell?

Tôi biết bạn không nên thực hành cưỡng bức thu gom rác - bạn chỉ nên tìm ra lý do tại sao vùng heap lớn/đang phát triển.

Tôi cũng nhận ra System.GC() không thực sự bắt buộc thu gom rác - nó chỉ cho GC biết rằng bạn muốn nó xảy ra.

Có nói rằng có cách nào để thực hiện việc này dễ dàng không? Một số ứng dụng dòng lệnh tôi đang thiếu?

+0

* Không * giống như http://stackoverflow.com/questions/1481178/how-to-force-garbage-collection-in-java – Raedwald

Trả lời

20

Bạn có thể thực hiện việc này thông qua chương trình miễn phí jmxterm.

cháy nó lên như vậy:

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

Từ đó, bạn có thể kết nối đến một máy chủ và kích hoạt 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 

Nhìn vào các tài liệu trên trang web jmxterm web để biết thông tin về nhúng điều này trong bash/perl/ruby ​​/ script khác. Tôi đã sử dụng popen2 trong Python hoặc open3 trong Perl để làm điều này.

UPDATE: đây là một lớp lót bằng jmxterm:

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

Tôi không nghĩ có tùy chọn dòng lệnh nào giống nhau.

Bạn sẽ cần sử dụng jvisualvm/jconsole cho tương tự.

Tôi muốn đề xuất bạn sử dụng những công cụ này để nhận dạng, tại sao chương trình của bạn có nhiều bộ nhớ.

Dù sao bạn không nên ép buộc GC, vì nó chắc chắn sẽ làm phiền thuật toán GC và làm cho chương trình của bạn chậm.

6

Có một vài giải pháp khác (rất nhiều người tốt ở đây đã được):

  • Viết một mã nhỏ để truy cập MemoryMBean và gọi gc().
  • Sử dụng một dòng lệnh JMX khách hàng (như cmdline-jmxclient, jxmterm) và chạy các hoạt động gc() trên MemoryMBean

Ví dụ sau đây là dành cho các cmdline-jmxclient:

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

này là tốt đẹp bởi vì nó chỉ có một dòng và bạn có thể đặt nó trong một kịch bản thực sự dễ dàng.

88

Nếu bạn chạy jmap -histo:live, sẽ buộc một GC đầy đủ trên heap trước khi nó in ra bất cứ điều gì.

+5

bây giờ * đó là * những gì tôi ' m nói về! – sourcedelica

+2

buộc một bộ sưu tập rác trên tất cả các javas: ps axf | grep java | grep -v grep | awk '{print' jmap -histo: live "$ 1} '| sh – gtrak

+0

Tài liệu đó ở đâu? Điều gì về mà không có: sống (ví dụ: khi -F là cần thiết)? – nafg

-6

chỉ:

kill -SIGQUIT <PID> 
+4

Điều này sẽ kích hoạt một đống rác không thu gom rác thải –

+0

ít nhất là solaris nó làm một lực lượng GC. –

+2

Không ngay cả trong Solaris, SIGQUIT sẽ kích hoạt không phải là GC hoặc một bãi chứa đống. SIGQUIT sẽ kích hoạt một chuỗi chỉ cho HotSpot. Đối với IBM JVM, nó có thể cấu hình được. –

221

Kể từ JDK 7 bạn có thể sử dụng công cụ lệnh JDK 'jcmd' như:

jcmd <pid> GC.run

+13

Tại sao bạn không nói với tôi về những điều này? :) – noahlz

+2

Chỉ là những gì tôi đang tìm kiếm, cảm ơn. –

+8

Đây không phải là câu trả lời được chấp nhận? – brunorey

0

Nếu bạn đang sử dụng jolokia với ứng dụng của bạn, bạn có thể kích hoạt bộ sưu tập rác với lệnh này:

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

Ngoài câu trả lời của user3198490. Chạy lệnh này có thể cung cấp cho bạn các thông báo lỗi sau đây:

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

Điều này có thể được giải quyết với sự giúp đỡ của this stackoverflow answer

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

nơi <process_owner> là người dùng có thể chạy các quá trình với PID <pid>. Bạn có thể nhận được cả hai từ top hoặc htop

Các vấn đề liên quan