2012-05-04 12 views
17

मैंने SO पर अन्य समान प्रश्नों को देखा है, लेकिन वे अन्य मुद्दों के कारण होते हैं।जेडीके 1.7: पॉज़िक्स सेमफोरस के कारण "बहुत सारी खुली फ़ाइलें"?

सबसे पहले मैंने सुनिश्चित किया कि मैंने अपने सभी फाइल हैंडल को समझदारी से बंद कर दिया है, और फिर मैंने फ़ाइलों की सूची देखने के लिए lsof -p <pid of java> का उपयोग किया।

यह मेरी क्रम में बहुत स्थिर रहती है, लेकिन फिर समय-समय पर मैं लगभग 10,000 प्रविष्टियों इस तरह lsof में सूचीबद्ध हो जाएगा:

COMMAND PID USER FD  TYPE DEVICE SIZE/OFF  NODE NAME 
             ... 
java 36809 smm *235r PSXSEM    0t0   kcms00008FC901624000 
java 36809 smm *236r PSXSEM    0t0   kcms00008FC901624000 
java 36809 smm *237r PSXSEM    0t0   kcms00008FC901624000 
java 36809 smm *238r PSXSEM    0t0   kcms00008FC901624000 
java 36809 smm *239r PSXSEM    0t0   kcms00008FC901624000 

आदमी पेज का कहना है PSXSEM प्रकार एक POSIX सेमाफोर है। कोई भी संकेत क्या जेडीके पॉज़िक्स सेमफोरस का उपयोग करता है? बीटीडब्ल्यू, इस समय ऐप एक सिंगल थ्रेडेड कमांड लाइन ऐप है।

संभावित रूप से उपयोगी पृष्ठभूमि: मैं पहले मैक ओएस एक्स 10.7.3 पर JDK 1.7 के उन्नयन के बाद यह देखा:

java version "1.7.0_04" 
Java(TM) SE Runtime Environment (build 1.7.0_04-b21) 
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode) 

अद्यतन: JDK 1.6 पर $JAVA_HOME repointing जारी करने के लिए एक समाधान हो रहा है।

java version "1.6.0_31" 
Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-11M3635) 
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode) 

जेडीके 1.7 अलग-अलग क्या कर रहा है?

+0

मैं आपके जावा लाइब्रेरी ऑब्जेक्ट की बड़ी संख्या बनाने के लिए 10K सेमफोरों के निर्माण को सहसंबंधित कर सकता हूं या नहीं, यह देखने के लिए कि आप अपने ट्रैक या यहां तक ​​कि केवल VisualVM जैसे नियमित जावा प्रोफाइलर का प्रयास करेंगे। –

+2

मुझे अभी भी यह समस्या दिखाई दे रही है, लेकिन मैं ImageIO का उपयोग नहीं कर रहा हूं (कम से कम सीधे नहीं)। पश्चाताप सिर्फ सेमेफोरों की संख्या में वृद्धि का कारण बनता है, जब तक मुझे कोई नहीं मिलता: 2012-05-09 16: 30: 12.856 जावा [14407: 3 डी 87] निरंतर यूआई फ़ाइल फ़ाइल खोलने में विफल रहा: // localhost/उपयोगकर्ता/juancn/लाइब्रेरी /Saved%20Application%20State/net.java.openjdk.cmd.savedState/window_1.data: बहुत सारी खुली फ़ाइलें (24) – juancn

उत्तर

7

मैं कोड के इस खंड के लिए नीचे पता लगाने में सक्षम था:

BufferedImage image = null; 
ImageInputStream stream = null; 
try { 
    stream = new FileImageInputStream(file); 
    image = ImageIO.read(stream); 

} catch (Exception ex) { 
    log.error("Image could not be read: "+file.getPath()); 

} finally { 
    // ImageIO closes input stream unless null is returned 
    // http://docs.oracle.com/javase/7/docs/api/javax/imageio/ImageIO.html#read(javax.imageio.stream.ImageInputStream) 
    if (stream != null && image == null) { 
     try { 
      stream.close(); 
     } catch (IOException ex) { 
      log.error("ERROR closing image input stream: "+ex.getMessage(), ex); 
     } 
    } 
} 

Javadocs विशेष रूप से कहना है कि इस विधि (दूसरों के विपरीत) स्वचालित रूप से धारा बंद कर देता है। वास्तव में, जब आप इसे मैन्युअल रूप से बंद करने का प्रयास करते हैं, तो यह 'बंद' कहकर अपवाद फेंकता है। मैं इस अधिभार का उपयोग कर रहा था क्योंकि दूसरे का कहना है कि यह ImageInputStream में इसे लपेटता है, इसलिए मैंने सोचा कि मैं कुछ काम बचाऊंगा।

ब्लॉक बदलने एक सामान्य FileInputStream फिक्स रिसाव उपयोग करने के लिए:

BufferedImage image = null; 
InputStream stream = null; 
try { 
    stream = new FileInputStream(file); 
    image = ImageIO.read(stream); 

} catch (Exception ex) { 
    log.error("Image could not be read: "+file); 

} finally { 
    if (stream != null) { 
     try { 
      stream.close(); 
     } catch (IOException ex) { 
      log.error("ERROR closing image input stream: "+ex.getMessage(), ex); 
     } 
    } 
} 

यह मुझे ऐसा लगता है JDK 1.7 में एक बग के रूप में 1.6 ठीक यहाँ काम किया जाना है।

अद्यतन: मैं इस मुद्दे के लिए ओरेकल में submitted a bug report पर हूं।

+0

दुर्भाग्य से यह 1.7.0_04 के रूप में ठीक नहीं लग रहा है, यह बहुत बुरा है हालांकि कोई अन्य नहीं है कल्पना में एपीआई जो आपको किसी छवि की वैधता की जांच करने की अनुमति देती है। हालांकि, मुझे लगता है कि आप भाग्यशाली हैं, मैं अभी भी जेईई कंटेनर को मारने वाले उन सेफफोर्स को प्राप्त कर रहा हूं। –

+0

@ आर्किमिडीज ट्राज़ानो मैंने अभी भी इस काम के साथ भी अंतःक्रियात्मक मुद्दों का सामना किया है। एक बहुत बुरा बग लगता है। – mckamey

+0

यह केवल जेपीईजी फाइलों पर है। चूंकि मैं केवल यह जांचने के लिए उपयोग करता हूं कि कोई जेपीईजी फ़ाइल "वैध" है या नहीं, मैं सिर्फ यह जांचता हूं कि इसमें उचित स्थान पर छवि का प्रारंभ और छवि का अंत है या नहीं। –

4

मुझे एक और कारण मिला। ऐसा लगता है कि कलरस्पेस की toRGB() विधि सेमफोर लीक कर रही है। निम्नलिखित कोड चल रहा है:

import java.awt.color.ColorSpace; 
public class Test 
{ 
    public static void main(String[] args) throws Throwable { 
     final ColorSpace CIEXYZ = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ); 
     for(int i = 0; i < 10000000; i++) { 
      CIEXYZ.toRGB(new float[] {80f, 100, 100}); 
     } 
    } 
} 

के साथ:

java version "1.7.0_04" 
Java(TM) SE Runtime Environment (build 1.7.0_04-b21) 
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode) 

आप सिस्टम फ़ाइलों से बाहर छोड़ देंगे।

संपादित करें: पहले से ही प्रस्तुत एक bug report ओरेकल

+0

अच्छा खोज। धन्यवाद। – mckamey

4

को अपडेट: के रूप में अन्य उपयोगकर्ताओं के कहा है, ImageIO 1.7.0_04 और 1.7.0_05 में संकेतबाहु लीक किया गया था। उपयोगकर्ता juancn और उपयोगकर्ता mckamey द्वारा बग रिपोर्ट को बाद में निश्चित और बंद (धन्यवाद दोस्तों!) के रूप में चिह्नित किया गया है।स्पष्टीकरण:

यह फ़िक्स मैकॉक्स पर फ़ाइल हैंडलर की रिसाव की रिपोर्ट करता है। इसने हैंडलर को रिसाव करने के दो तरीकों का उल्लेख किया: ImageIO.read (ImageInputStream) के माध्यम से, और सेमफोर के माध्यम से।

मुझे पहली रिसाव नहीं दिखाई देती है: अगर हम उचित पाठक पाते हैं तो हम स्पष्ट रूप से इनपुट स्ट्रीम बंद करते हैं, और फ़ाइल हैंडल जारी करने के लिए यह पर्याप्त (कम से कम 1.7.4) है।

हालांकि, सेमाफोर के मामले में हम हैंडल की टन रिसाव: हम jpeg छवि की प्रत्येक पंक्ति में रंग रूपांतरण करते हैं, और हर बार जब हम एक सेमाफोर बनाने (क्योंकि हम 2 या अधिक सीपीयू सिस्टम पर स्थापित देखें), तो हम अलग-अलग कार्यों की संख्या को 1 तक घटाते हैं (क्योंकि हमारे पास प्रक्रिया के लिए एकल स्कैन लाइन है) और इसके कारण सेमफोर को कभी अनलिंक नहीं किया जाता है।

लिनक्स सिस्टम पर एक ही समस्या मौजूद है, लेकिन कम डिग्री में क्योंकि हम नामित सेमफोर प्रति फ़ाइल हैंडल पर कब्जा करते हैं, जबकि मैकॉक्स पर हम हमेशा नई फ़ाइल हैंडल पर कब्जा करते हैं।

सुझाए ठीक बस नामित सेमाफोर के निर्माण स्थगित जब तक हम अलग कार्यों की संख्या स्पष्ट है, इसलिए, अब हम छवि पढ़ने और सरल रंग रूपांतरण के लिए सेमाफोर का निर्माण नहीं करतीं (ColorSpace.toRGB की तरह())। इसके अलावा, अब हम सैमफोर विनाश के लिए ट्रिगर के रूप में पीएसईएम सूचक का उपयोग करते हैं।

हालांकि उनकी रिपोर्टों से संकेत मिलता है कि ठीक संस्करण 8 में है, बैकपोर्ट रिपोर्ट इंगित करता है कि यह था fixed in 1.7.0_06.

तो अगर आप 1.7.0_04 या 05 पर इस को देख रहे हैं, कम से कम 1.7 के लिए अद्यतन करने .0_06 इस मुद्दे का ख्याल रखेगा।

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