2016-07-08 19 views
6

संदर्भ: मैं जावा आधारित नेटवर्क सर्वर पर काम कर रहा हूं जो गलती से पाइप लीक करता है। हर कुछ दिनों में यह 40,000 फाइल डिस्क्रिप्टर की सीमा को हिट करता है और मर जाता है। मृत्यु से पहले सर्वर पर lsof का उपयोग करके यह दिखाता है कि यह पाइप के साथ दबाया जाता है। पाइप एक और प्रक्रिया के बजाय खुद से जुड़ते हैं।जब एक विशिष्ट सिस्टम कॉल किया जाता है तो जावा स्टैक-ट्रेस रिकॉर्ड करना?

कोडबेस का कोई भी हिस्सा पाइप बनाता है या उपयोग नहीं करता है - जिसे हम देख सकते हैं।

जेवीएम के कुछ पुराने संस्करण ने & सॉकेट बनाने के दौरान एक पाइप लीक की है, हालांकि यह जावा 1.7.0_75 पर प्रदर्शित होता है जो मुझे विश्वास है कि उस बग को पीड़ित नहीं है।

मेरा प्रश्न है: आधुनिक लिनक्स toolchain, (जैसे पर्फ़ के रूप में) का उपयोग करते हुए यह प्रक्रिया स्नैपशॉट करने के लिए संभव है, जब यह pipe(2) सिस्टम कॉल कहता है - जो मेरा मानना ​​है कि एक ही रास्ता पाइप बनाई गई हैं है। इसके अलावा, क्या उस से जावा स्टैक-ट्रेस पुनर्प्राप्त करना संभव है?

इस जानकारी को देखते हुए सवाल उठाना संभव है कि "कौन पाइप बना रहा है, और क्यों?"

+0

मैं सुझाव है कि आप 'लीक कर रहे हैं Selectors' सहित यह करने के लिए पर विभिन्न अन्य गाइड कर रहे हैं। – EJP

+0

अपने स्वयं के फ़ंक्शन के साथ 'पाइप' को प्रतिस्थापित करने के लिए LD_PRELOAD का उपयोग करने पर विचार करें। – Nykakin

+0

@EJP - एक आकर्षक विचार। आप उससे ठोस निदान कैसे कर सकते हैं? –

उत्तर

3

जावा 1.7.0_75 (या प्री-जावा 8 अपडेट 60) पर आप केवल घटना के कॉल स्टैक पर perf से सीमित जानकारी प्राप्त कर सकते हैं क्योंकि स्टैक को छोटा कर दिया जाएगा (नीचे देखें)।

आप पाइप पर सिस्टम कॉल पर सिस्टमव्यापी ट्रेसपॉइंट ईवेंट प्राप्त कर सकते हैं और निम्न perf कमांड, या इसी तरह के साथ बंद कर सकते हैं। उत्पादन में चलाने से पहले एक परीक्षण प्रणाली पर

  1. टेस्ट:

    perf record -e 'syscalls:sys_enter_pipe*' -e 'syscalls:sys_enter_close' -ag -- sleep 10 
    

    पूर्ण ढेर प्राप्त करने के लिए।

  2. जावा 8 अद्यतन 60 को स्थापित करें या बाद में
  3. साथ -XX
  4. भागो जावा: + PreserveFramePointer छोटा कर दिया ढेर
  5. वैकल्पिक रूप से बचने के लिए (के रूप में यह उत्पादन के लिए तैयार कोड नहीं है) स्थापित करें और करने के लिए Github से पर्फ़-नक्शा-एजेंट को चलाने जब इस मुद्दे को tracepoint घटनाओं और जुड़े ढेर उत्पादन के लिए
  6. रन "पर्फ़ स्क्रिप्ट" हो रहा है पर्फ़ के उपयोग
  7. भागो ऊपर या इसी तरह की "रिकॉर्ड पर्फ़" के लिए जावा JIT प्रतीकों को हल

निशान एक छोटा कर दिया ढेर मर्जी पर्फ़ को हल करने की अनुमति देने के पर्फ़-नक्शा-एजेंट के साथ

java 21553 [009] 10601254.522385: syscalls:sys_enter_pipe: fildes: 0x7f545322f340 
     7f54527180b7 __pipe (/usr/lib64/libc-2.17.so) 
     7f543d007760 [unknown] (/tmp/perf-21552.map) 
     7f543d0007a7 [unknown] (/tmp/perf-21552.map) 
     7f5451ce1be6 JavaCalls::call_helper (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5451fe7b27 Reflection::invoke (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5451feb237 Reflection::invoke_method (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5451d705fb JVM_InvokeMethod (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f543da669ed [unknown] (/tmp/perf-21552.map) 
     7f543d0007a7 [unknown] (/tmp/perf-21552.map) 
     7f5451ce1be6 JavaCalls::call_helper (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5451d23182 jni_invoke_static (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5451d3fb8a jni_CallStaticVoidMethod (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5452bfcbcc JavaMain (/usr/java/jdk1.8.0_60/jre/lib/amd64/jli/libjli.so) 
     7f5452e12df5 start_thread (/usr/lib64/libpthread-2.17.so) 

रन:

java 19575 [018] 10600910.346655: syscalls:sys_enter_pipe: fildes: 0x7f353b9f7f80 
     7f3809cff0b7 __pipe (/usr/lib64/libc-2.17.so) 
     7f37f59aecb9 [unknown] (/tmp/perf-19375.map) 
     7f37f5e83150 [unknown] (/tmp/perf-19375.map) 
    edb4639ef8034082 [unknown] ([unknown]) 

एक पूर्ण ढेर अधिक की तरह लग रहे हो सकता है: एक है कि उदाहरण के लिए तल पर धागा शुरू समारोह नहीं है हो सकता है जावा विधियों के लिए जिंदा [अज्ञात] कार्यों।

कैसे ब्रेंडन ग्रेग के काम http://techblog.netflix.com/2015/07/java-in-flames.html

संबंधित मुद्दे

 संबंधित मुद्दे