दिलचस्प पोस्ट
ग्राफ से मिलान करने के लिए Matplotlib रंग बार आकार सेट करें कैसे Base64 एन्कोडिंग में node.js करना है? डेकोरेटिंग डीईएक्स में जावा स्रोतकोड सी-ऑब्जेक्ट सी क्लास को सी + ऑब्जेक्ट जोड़ना String.xml का उपयोग कर गतिशील स्ट्रिंग? UIButton कस्टम फ़ॉन्ट वर्टिकल संरेखण ReactJS में इस। स्टेटीज और this.setstate के अंतर क्या है? मैं बेस 64 एन्कोडेड स्ट्रिंग को कैसे डीकोड कर सकता हूं? अपने एंड्रॉइड लाइब्रेरी मॉड्यूल में क्रॉसवाक वेबव्यू को कैसे जोड़ें? सी # में यूआरएल से शीर्ष स्तरीय डोमेन jQuery UI संवाद OnBeforeUnload एंड्रॉइड टूलबार: लैंडस्केप मोड में छोटा शीर्षक टेक्स्ट वीबी 6 से वेब सेवा का उपभोग करने का सबसे अच्छा तरीका क्या है? एक ढांचे और एक पुस्तकालय के बीच क्या अंतर है? NSDate से NSDate को समयक्षेत्र के साथ समायोजित करें

अंतिम 8 (8) में जावा 8 में जोरदार पहुंचने योग्य वस्तु

हमने हाल ही में अपने संदेश प्रसंस्करण आवेदन को जावा 7 से जावा 8 से उन्नत किया है। अपग्रेड के बाद से, हमें कभी-कभी अपवाद मिलता है कि एक स्ट्रीम बंद हो गई है, जब इसे पढ़ा जा रहा है। लॉगिंग से पता चलता है कि अंतिम वस्तु वाला थ्रेड स्ट्रीम (जो बारी में धारा बंद करता है) को धारण करने वाले ऑब्जेक्ट पर finalize() से कॉल कर रहा है

कोड की मूल रूपरेखा निम्नानुसार है:

 MIMEWriter writer = new MIMEWriter( out ); in = new InflaterInputStream( databaseBlobInputStream ); MIMEBodyPart attachmentPart = new MIMEBodyPart( in ); writer.writePart( attachmentPart ); 

MIMEWriter और MIMEBodyPart एक घर बढ़े MIME / HTTP पुस्तकालय का हिस्सा हैं। MIMEBodyPart प्रदान HTTPMessage , जिसमें निम्न है:

 public void close() throws IOException { if ( m_stream != null ) { m_stream.close(); } } protected void finalize() { try { close(); } catch ( final Exception ignored ) { } } 

अपवाद MIMEWriter.writePart की MIMEWriter.writePart श्रृंखला में MIMEWriter.writePart , जो निम्नानुसार है:

  1. MIMEWriter.writePart() भाग के लिए हेडर लिखता है, फिर part.writeBodyPartContent( this ) कॉल part.writeBodyPartContent( this )
  2. MIMEBodyPart.writeBodyPartContent() आउटपुट में सामग्री स्ट्रीम करने के लिए हमारी उपयोगिता विधि IOUtil.copy( getContentStream(), out ) MIMEBodyPart.writeBodyPartContent() कॉल करता है
  3. MIMEBodyPart.getContentStream() बस MIMEBodyPart.getContentStream() ऊपर कोड ब्लॉक देखें) में पारित इनपुट स्ट्रीम देता है
  4. IOUtil.copy पास एक लूप है जो इनपुट स्ट्रीम से एक 8K हिस्सा पढ़ता है और इसे इनपुट स्ट्रीम तक खाली करने तक लिखता है।

MIMEBodyPart.finalize() को IOUtil.copy चल रहा है, जबकि कहा जाता है, और इसे निम्नलिखित अपवाद मिलता है:

 java.io.IOException: Stream closed at java.util.zip.InflaterInputStream.ensureOpen(InflaterInputStream.java:67) at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:142) at java.io.FilterInputStream.read(FilterInputStream.java:107) at com.blah.util.IOUtil.copy(IOUtil.java:153) at com.blah.core.net.MIMEBodyPart.writeBodyPartContent(MIMEBodyPart.java:75) at com.blah.core.net.MIMEWriter.writePart(MIMEWriter.java:65) 

हमने कुछ लॉगिंग को HTTPMessage.close() विधि में दर्ज किया है जो कॉलर के स्टैक ट्रेस को लॉग इन करता है और साबित करता है कि यह निश्चित रूप से HTTPMessage.finalize() धागा है जो IOUtil.copy() का उपयोग कर रहा है IOUtil.copy() चल रहा है।

MIMEBodyPart ऑब्जेक्ट वर्तमान धागे के स्टैक से निश्चित रूप से पहुंच योग्य है क्योंकि this MIMEBodyPart.writeBodyPartContent लिए स्टैक फ्रेम में है। मुझे समझ नहीं आ रहा है कि क्यों JVM finalize() कॉल करेगा finalize()

मैंने प्रासंगिक कोड को निकालने और इसे अपनी मशीन पर एक तंग लूप में चलाने की कोशिश की, लेकिन मैं समस्या को पुन: उत्पन्न नहीं कर सकता। हम अपने देव सर्वर में से किसी एक पर उच्च भार के साथ समस्या को पुन: उत्पन्न कर सकते हैं, लेकिन छोटे पुन: उत्पादक परीक्षण केस बनाने की कोई भी कोशिश विफल रही है। कोड जावा 7 के तहत संकलित किया गया है, लेकिन जावा 8 के तहत कार्यान्वित किया गया है। अगर हम पुनः कंपाइलिंग के बिना जावा 7 पर वापस जाते हैं, तो समस्या उत्पन्न नहीं होती है।

एक वैकल्पिक हल के रूप में, मैंने जावा मेल MIME पुस्तकालय का उपयोग करके प्रभावित कोड को फिर से लिखा है और समस्या दूर हो गई है (संभवतः जावा मेल finalize() उपयोग नहीं करता है) हालांकि, मुझे चिंतित है कि आवेदन में अन्य को finalize() को गलत तरीके से बुलाया जा सकता है, या जावा अभी भी उपयोग में आने वाली वस्तुओं को कचरा-इकट्ठा करने की कोशिश कर रहा है।

मुझे पता है कि वर्तमान सर्वोत्तम अभ्यास finalize() का उपयोग करने की सिफारिश करता है और मैं संभवत: finalize() तरीकों को हटाने के लिए इस finalize() लाइब्रेरी को फिर से आऊंगा। कहा जा रहा है, किसी को इस मुद्दे से पहले आ गया है? क्या किसी के पास इस कारण के बारे में कोई विचार है?

Solutions Collecting From Web of "अंतिम 8 (8) में जावा 8 में जोरदार पहुंचने योग्य वस्तु"

अनुमान के एक बिट यहाँ। किसी ऑब्जेक्ट को अंतिम रूप दिया जा सकता है और कचरा इकट्ठा किया जा सकता है, भले ही स्टैक पर स्थानीय चर में इसका संदर्भ हो, और यहां तक ​​कि स्टैक पर उस ऑब्जेक्ट की एक इंस्टेंस विधि के लिए एक सक्रिय कॉल भी हो! आवश्यकता यह है कि ऑब्जेक्ट अप्राप्य हो । भले ही यह स्टैक पर है, अगर कोई भी बाद वाला कोड संदर्भ को छूता है, तो यह संभावित रूप से पहुंच योग्य नहीं है

एक उदाहरण के लिए इस अन्य उत्तर को देखें कि एक ऑब्जेक्ट जीसी के तौर पर कैसे हो सकता है, जबकि एक स्थानीय चर संदर्भ में अभी भी क्षेत्र में है।

एक उदाहरण विधि कॉल सक्रिय होने पर एक ऑब्जेक्ट को अंतिम रूप दिया जा सकता है इसका उदाहरण यहां दिया गया है:

 class FinalizeThis { protected void finalize() { System.out.println("finalized!"); } void loop() { System.out.println("loop() called"); for (int i = 0; i < 1_000_000_000; i++) { if (i % 1_000_000 == 0) System.gc(); } System.out.println("loop() returns"); } public static void main(String[] args) { new FinalizeThis().loop(); } } 

जबकि loop() विधि सक्रिय है, किसी भी कोड को FinalizeThis से इस ऑब्जेक्ट के संदर्भ के साथ कुछ भी करने की कोई संभावना नहीं है, इसलिए यह पहुंच से बाहर नहीं है। और इसलिए इसे अंतिम रूप दिया जा सकता है और जीसी'एद। जेडीके 8 जीए पर, यह निम्नलिखित छापती है:

 loop() called finalized! loop() returns 

हर बार।

MimeBodyPart साथ कुछ ऐसा ही हो सकता है क्या यह एक स्थानीय चर में संग्रहीत किया जा रहा है? (ऐसा लगता है, क्योंकि कोड एक ऐसे सम्मेलन का पालन करते हुए लगता है कि फ़ील्ड को m_ उपसर्ग के साथ नाम दिया गया है।)

अद्यतन करें

टिप्पणियों में, ओपी ने निम्नलिखित परिवर्तन का सुझाव दिया:

  public static void main(String[] args) { FinalizeThis finalizeThis = new FinalizeThis(); finalizeThis.loop(); } 

इस बदलाव के साथ उन्होंने अंतिम रूप से निरीक्षण नहीं किया, और न ही मैं भी करता हूं। हालांकि, अगर यह और बदलाव किया जाता है:

  public static void main(String[] args) { FinalizeThis finalizeThis = new FinalizeThis(); for (int i = 0; i < 1_000_000; i++) Thread.yield(); finalizeThis.loop(); } 

अंतिम रूप से एक बार फिर होता है मुझे संदेह है कि लूप के बिना, main() विधि का अर्थ है, संकलित नहीं है। शायद व्याख्यात्मक विश्लेषण के बारे में दुभाषिया कम आक्रामक है। जगह में उपज लूप के साथ, main() विधि संकलित हो जाती है, और जेआईटी संकलक को finalizeThis पता लगाता है कि loop() विधि निष्पादित हो रही है, यह बिना पहुंच योग्य हो गई है।

इस व्यवहार को ट्रिगर करने का एक और तरीका है -Xcomp विकल्प को JVM में उपयोग करना, जो निष्पादन से पहले जेआईटी-संकलित होने के तरीकों को -Xcomp करता है। मैं एक पूरा आवेदन इस तरह से नहीं चलाता- जेआईटी-संकलन सब कुछ बहुत धीमा हो सकता है और बहुत सारे स्थान ले सकता है – लेकिन छोरों के साथ छेड़ने के बजाय छोटे परीक्षण कार्यक्रमों में इस तरह के मामलों को फ्लश करने में उपयोगी है

आपका फ़ाइनलर सही नहीं है

सबसे पहले, इसे कैच ब्लॉक की आवश्यकता नहीं है, और इसे अपने finally{} ब्लॉक में super.finalize() को कॉल करना होगा। एक अंतिम रूप का वैमनिक रूप निम्नानुसार है:

 protected void finalize() throws Throwable { try { // do stuff } finally { super.finalize(); } } 

दूसरे, आप मानते हैं कि आप केवल m_stream संदर्भ को m_stream , जो सही या सही नहीं हो सकता है m_stream सदस्य को स्वयं को अंतिम रूप देना चाहिए लेकिन आपको यह पूरा करने के लिए कुछ भी करने की ज़रूरत नहीं है अंततः m_stream एक m_stream या m_stream स्ट्रीम या एक सॉकेट स्ट्रीम होगा, और वे खुद को सही ढंग से अंतिम रूप से अंतिम रूप दे देंगे।

मैं इसे हटा दूंगा