आप शैल से गारबेज कलेक्शन कैसे करते हैं?


106

इसलिए मैं एक रिमोट बॉक्स पर जम्प के साथ एक ढेर को देख रहा हूं और मैं उस पर कचरा संग्रह करना चाहता हूं। आप jvisualvm या jconsole और दोस्तों में पॉपिंग के बिना यह कैसे करते हैं?

मुझे पता है कि आपको कचरा संग्रहण के लिए मजबूर नहीं होना चाहिए - आपको यह पता लगाना चाहिए कि ढेर बड़ा / बढ़ता क्यों है।

मुझे यह भी एहसास है कि System.GC () वास्तव में कचरा संग्रहण के लिए बाध्य नहीं करता है - यह सिर्फ GC को बताता है कि आप इसे घटित करना चाहेंगे।

कहा कि आसानी से ऐसा करने का कोई तरीका है? कुछ कमांड लाइन ऐप मुझे याद आ रही है?


नहीं के रूप में stackoverflow.com/questions/1481178/…
Raedwald

जवाबों:


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 ​​/ अन्य लिपियों में एम्बेड करने की जानकारी के लिए jmxterm वेब साइट पर डॉक्स देखें। मैंने ऐसा करने के लिए पायथन में popen2 या पर्ल में ओपन 3 का उपयोग किया है।

अद्यतन: यहाँ 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
आप लोग मुझे इन बातों के बारे में क्यों नहीं बताते ?! :)
नोहलज़

2
यदि आपको "AttachNotSupportedException: सॉकेट फ़ाइल खोलने में असमर्थ" मिलता है, तो इस उत्तर के लिए मेरा जोड़
थॉमस रेबेले

और अगर आप VM तर्क के Explicit GC is disabled, no GC has been performedकारण हो रहे हैं -XX:+DisableExplicitGC। देखें: mail.openjdk.java.net/pipermail/serviceability-dev/2017-August/…
रोथ

यह केवल Oracle JDK के लिए काम करेगा, यह ओपन-jdk के लिए काम नहीं करेगा।
अली सालेह

104

यदि आप दौड़ते हैं jmap -histo:live <pid>, तो इससे पहले कि यह कुछ भी बाहर प्रिंट करता है, ढेर पर एक पूर्ण जीसी मजबूर करेगा।


3
सभी javas पर एक कचरा संग्रह के लिए मजबूर करें: ps axf | grep जावा | grep -v grep | awk '{print "jmap -histo: live" $ 1}'। sh
gtrak

1
वह दस्तावेज कहां है? बिना इसके बारे में क्या: जीना (जैसे कब -F की जरूरत है)?
nafg

7
2014 के रहस्यमय भविष्य से नमस्ते। jcmdअब नौकरी के लिए सही उपकरण है।
नूह

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

इसे इस स्टैकओवरफ्लो उत्तर की मदद से हल किया जा सकता है

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

<process_owner>पीआईडी ​​के साथ प्रक्रिया चलाने वाला उपयोगकर्ता कहां है <pid>। आप दोनों से topया प्राप्त कर सकते हैंhtop


निम्नलिखित के बारे में क्या? वही चीज? java.io.IOException: Operation not permitted
19

मुझे यह त्रुटि संदेश अभी तक नहीं मिला है। शायद यह साथ काम करता है sudo -u <process_owner> jcmd <pid> GC.run, क्या आप कोशिश कर सकते हैं? कमांड सुरक्षित होना चाहिए
थॉमस रेबेले

मेरे पास होगा, लेकिन मुझे उस मशीन पर सुडो एक्सेस नहीं है।
डेकी हॉकी

उपकरण सही ढंग से काम करता है। इसे निष्पादित करने के लिए आपके पास ऑपरेटिंग सिस्टम की सही अनुमति नहीं है। वही अन्य अनुप्रयोगों पर भी लागू होता है, यहां तक ​​कि जावा का उपयोग भी नहीं।
aled

6

कुछ अन्य समाधान हैं (पहले से ही बहुत से अच्छे हैं):

  • MemoryMBean तक पहुंचने और कॉल करने के लिए थोड़ा कोड लिखें gc()
  • कमांड-लाइन JMX क्लाइंट (जैसे cmdline-jmxclient , jxmterm ) का उपयोग करना और gc()मेमोरीएमबीएन पर ऑपरेशन चलाना

Cmdline-jmxclient के लिए निम्न उदाहरण है:

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

यह अच्छा है क्योंकि यह केवल एक पंक्ति है और आप इसे स्क्रिप्ट में वास्तव में आसानी से डाल सकते हैं।


5

लिनक्स के लिए:

$ jcmd $(pgrep java) GC.run

jcmdJDK के साथ पैक किया गया है, $(pgrep java)जावा की प्रक्रिया आईडी प्राप्त करता है


यह केवल तभी काम करेगा जब एक जावा प्रक्रिया चल रही हो। अन्यथा यह jcmd के लिए कमांड के रूप में दूसरी पीआईडी ​​की व्याख्या करेगा जो स्पष्ट रूप से मान्यता प्राप्त नहीं है और एक त्रुटि फेंकती है।
कैस एलियन्स

0

मुझे नहीं लगता कि इसके लिए कोई कमांड लाइन विकल्प है।

आपको उसी के लिए jvisualvm / jconsole का उपयोग करना होगा।

मैं आपको यह सुझाव देना चाहूंगा कि पहचान के लिए इन उपकरणों का उपयोग करें, क्यों आपका कार्यक्रम मेमोरी पर अधिक है।

वैसे भी आपको GC को बाध्य नहीं करना चाहिए, क्योंकि यह निश्चित रूप से GC एल्गोरिथ्म को परेशान करेगा और आपके प्रोग्राम को धीमा कर देगा।


0

यदि आप अपने एप्लिकेशन के साथ जोलोकिया का उपयोग कर रहे हैं , तो आप इस आदेश के साथ कचरा संग्रह को ट्रिगर कर सकते हैं:

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

-10

बस:

kill -SIGQUIT <PID>

4
यह एक ढेर डंप करेगा कचरा संग्रह नहीं
ड्रोर बेरेज़निट्सकी

कम से कम सोलारिस है यह एक बल GC करता है।
अमीन अब्बासूर

2
Solaris में भी नहीं, SIGQUIT न तो GC या ढेर डंप को ट्रिगर करेगा। SIGQUIT केवल हॉटस्पॉट के लिए एक थ्रेड डंप ट्रिगर करेगा। IBM JVM के लिए यह विन्यास योग्य है।
Mircea Vutcovici

जीसी को ट्रिगर नहीं करेगा, बस स्टैक ट्रेस प्रिंट करें।
एलाड तबक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.