2014-10-19 11 views
15

मैं कक्षा गतिशील पैदा करते हैं और लोड यहJava8 metaspace और ढेर उपयोग

import javassist.CannotCompileException; 
import javassist.ClassPool; 

public class PermGenLeak { 
    private static final String PACKAGE_NAME = "com.jigarjoshi.permgenleak."; 

    public static void main(String[] args) throws CannotCompileException, InterruptedException { 
     for (int i = 0; i < Integer.MAX_VALUE; i++) { 
      ClassPool pool = ClassPool.getDefault(); 
      pool.makeClass(PACKAGE_NAME + i).toClass(); 
      Thread.sleep(3); 
     } 

    } 
} 

मैं जावा 7 (jdk1.7.0_60) के खिलाफ इस वर्ग का शुभारंभ किया और उम्मीद के रूप में यह PermGenSpace भरा और ढेर अप्रयुक्त बने रहे के लिए इस कोड है Java 7 memory usage छवि permgen उपयोग अतिरिक्त समय पता चलता है और अंत JVM पर

अब एक ही कोड जावा 8 (jdk1.8.0_40-EA) के खिलाफ दौड़ा समाप्त किया गया है और उम्मीद के रूप में यह देशी स्मृति (Metaspace) लेकिन आश्चर्यजनक रूप से के लिए विस्तार हो रहा रखा मेटास्पैस के 1 जी ने ओल्डजेन (एल्मोस) में 3 जी ढेर का सेवन किया Metaspace की टी 3x समय)

Java8 memory usage छवि दिखाता Metaspace उपयोग अतिरिक्त समय और सिस्टम स्मृति के उपयोग नमूना

this email from Jon Masamitsu और this JEP ticket कहते

प्रशिक्षु String और कक्षा आँकड़े और कुछ विविध डेटा है से अधिक बनाए रखा ढेर

ढेर में इस वृद्धि को वास्तव में क्या बनाता है क्योंकि यह मेटास्पेस में अधिक कक्षाएं लोड करता है?

उत्तर

10

jmap -histo PID रन करें कि कौन सी वस्तुएं हीप स्पेस का उपभोग करती हैं।
जब मैं अपने उदाहरण भाग गया मैं ढेर Javassist सहायक वस्तुओं से भरा देखा:

num  #instances   #bytes class name 
---------------------------------------------- 
    1:  592309  312739152 [Ljavassist.bytecode.ConstInfo; 
    2:  6515673  208501536 java.util.HashMap$Node 
    3:  2964403  169188824 [C 
    4:  1777622  102165184 [Ljava.lang.Object; 
    5:  4146200  99508800 javassist.bytecode.Utf8Info 
    6:  3553889  85293336 java.util.ArrayList 
    7:  2964371  71144904 java.lang.String 
    8:  593075  56944008 java.lang.Class 
    9:  592332  47388032 [Ljava.util.HashMap$Node; 
    10:  592309  37907776 javassist.bytecode.ClassFile 
    11:  592308  37907712 javassist.CtNewClass 
    12:  1185118  28555808 [B 
    13:  592342  28432416 java.util.HashMap 
    14:  1184624  28430976 javassist.bytecode.ClassInfo 
    15:  592309  28430832 [[Ljavassist.bytecode.ConstInfo; 
    16:  592322  23692880 javassist.bytecode.MethodInfo 
    17:  592315  23692600 javassist.bytecode.CodeAttribute 
    18:  592434  18957888 java.util.Hashtable$Entry 
    19:  592309  18953888 javassist.bytecode.ConstPool 
    20:  592308  18953856 java.lang.ref.WeakReference 
    21:  592318  14215632 javassist.bytecode.MethodrefInfo 
    22:  592318  14215632 javassist.bytecode.NameAndTypeInfo 
    23:  592315  14215560 javassist.bytecode.ExceptionTable 
    24:  592309  14215416 javassist.bytecode.LongVector 
    25:  592309  14215416 javassist.bytecode.SourceFileAttribute 
    26:  592507  9487584 [I 
    27:    8  6292528 [Ljava.util.Hashtable$Entry; 
    28:   212   18656 java.lang.reflect.Method 
    29:   407   13024 java.util.concurrent.ConcurrentHashMap$Node 
    30:   124   8928 java.lang.reflect.Field 
+0

में क्यों नहीं देखा धन्यवाद एंड्री, मुझे बस इसे निष्पादित करना चाहिए था, मुझे लगता है कि मैं जावा 7 में इस पैमाने पर नहीं पहुंच पाया था इसलिए मैंने इसे जावा 7 में नहीं देखा –

3

वास्तव में क्या ढेर में इस वृद्धि के रूप में यह Metaspace में और अधिक वर्गों को लोड करता है?

मेरी परिकल्पना यह है कि यह "सामान्य" कचरा है जो आपके उदाहरण द्वारा बनाया जा रहा है।

  • javaassist कोड नियमित ढेर वस्तुओं बनाता है: मुझे लगता है कि समझ में आता। वे ज्यादातर "बड़े" होते हैं और इससे उन्हें ओल्डजेन ढेर में सीधे आवंटित किया जाता है। या कुछ और कारण बनता है।

    (अद्यतन - @ apangin के उत्तर को देख, मैं अब संदेह है कि वे YoungGen ढेर में बाहर शुरू कर दिया और पर्याप्त थे ...)

  • classLoader.defineClass हुड के नीचे बुलाया है, यह में वस्तुओं बनाता है क्लासफाइल युक्त बाइट सरणी से मेटास्पेस।

  • ओल्डजेन उपयोग बनी हुई है ... क्योंकि अभी तक कुछ भी पूर्ण जीसी ट्रिगर नहीं हुआ है।

आप अपने उदाहरण बदलाव यदि ऐसा है कि कक्षाओं में पहुंच योग्य थे, और फिर एक पूर्ण जीसी मजबूर, मैं (आशा) OldHeap उपयोग ड्रॉप करने को देखने के लिए उम्मीद करेंगे, यह दर्शाता है "साधारण" कचरा यह है कि बजाय एक भंडारण रिसाव।

+0

धन्यवाद स्टीफन, यह पूरी तरह से अब कोई मतलब, मुझे लगता है कि मैं जावा 7 उदाहरण में आवंटन के इस पैमाने पर है कि कम से नहीं पहुंचे मैंने इसे जावा 7 –

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