2015-05-25 4 views
7

हमारे कुछ अनुप्रयोगों के लिए सीएमएस से जी 1 तक जाने के दौरान, मैंने देखा कि उनमें से एक कारक द्वारा विस्तारित स्टार्टअप समय से पीड़ित है। जीसी चक्रों के कारण आवेदन रोक समय कारण नहीं है। आवेदन व्यवहार की तुलना करने पर, मैंने यह खुलासा किया कि स्टार्टअप (12 जी के ढेर में) के बाद इसमें 250 मिलियन जीवित वस्तुओं की एक बड़ी वस्तु है। आगे की जांच से पता चला कि आवेदन के पहले 5 मिलियन आवंटन के दौरान सामान्य गति थी, लेकिन प्रदर्शन अधिक से अधिक गिरावट आई क्योंकि लाइव ऑब्जेक्ट्स का पूल बड़ा हो गया।क्या G1 का उपयोग करते समय आवंटन प्रदर्शन बड़ी संख्या में लाइव उदाहरणों पर गिरावट करता है?

आगे के प्रयोगों से संकेत मिलता है कि एक बार जीवित वस्तुओं की एक निश्चित दहलीज तक पहुंचने के बाद, नई वस्तुओं का आवंटन वास्तव में जी 1 का उपयोग करते समय धीमा हो जाएगा। मैंने पाया कि जीवित वस्तुओं की संख्या दोगुना करने के लिए उस आवंटन के लिए आवश्यक समय पर लगभग 2.5 का कारक लगाया जाता है। अन्य जीसी इंजनों के साथ, कारक केवल 2 है। यह वास्तव में मंदी की व्याख्या करेगा।

  • मोटे तौर पर लगभग 5 लाख लाइव उदाहरणों की दहलीज एक पूरे के रूप ढेर से संबंधित प्रतीत हो रहा है:

    दो मुद्दे हैं जो मुझे उस निष्कर्ष पर शक करना है, हालांकि रहे हैं। जी 1 के साथ, मुझे उम्मीद है कि इस तरह के किसी भी अपमानजनक दहलीज को एक क्षेत्र से संबंधित किया जा रहा है, न कि पूरे ढेर के लिए।

  • मैंने वेब पर दस्तावेज़ों के बारे में बताया (या कम से कम बता रहा है), लेकिन मुझे कोई नहीं मिला। मुझे इस तरह की सिफारिशें भी नहीं मिलीं कि 'xxx लाइव ऑब्जेक्ट्स से ज्यादा बुराई' है।

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

यहाँ एक छोटी परीक्षण का मामला (कई बार चलाने के लिए, मतलब मूल्यों ले, घटा दिखाया गया कचरा संग्रहण बार) है:

आपका परीक्षण:

import java.util.HashMap; 

/** 
    * Allocator demonstrates the dependency between number of live objects 
    * and allocation speed, using various GC algorithms. 
    * Call it using, e.g.: 
    * java Allocator -Xmx12g -Xms12g -XX:+PrintGCApplicationStoppedTime -XX:+UseG1GC 
    * java Allocator -Xmx12g -Xms12g -XX:+PrintGCApplicationStoppedTime 
    * Deduct stopped times from execution time. 
    */ 
public class Allocator { 

public static void main(String[] args) { 
    timer(2000000, true); 
    for (int i = 1000000; i <= 32000000; i*=2) { 
     timer(i, false); 
    } 
    for (int i = 32000000; i >= 1000000; i/=2) { 
     timer(i, false); 
    } 
} 

private static void timer(int num, boolean warmup) { 
    long before = System.currentTimeMillis(); 
    Allocator a = new Allocator(); 
    int size = a.allocate(num); 
    long after = System.currentTimeMillis(); 
    if (!warmup) { 
     System.out.println("Time needed for " + num + " allocations: " 
      + (after - before) + " millis. Map size = " + size); 
    } 
} 

private int allocate(int numElements) { 
    HashMap<Integer, String> map = new HashMap<>(2*numElements); 
    for (int i = 0; i < numElements; i++) { 
     map.put(i, Integer.toString(i)); 
    } 
    return map.size(); 
} 

} 
+0

जीसी लॉग ('प्रिंटजीसीडीईटीई' के माध्यम से) और आपके द्वारा उपयोग किए जा रहे जावा संस्करण का उल्लेख करना उपयोगी होगा – the8472

+0

वास्तविक एप्लिकेशन का पूर्ण जीसी लॉग बहुत बड़ा है।:) लेकिन वैसे भी, उपरोक्त परीक्षण केस व्यवहार प्रदर्शित करता है। कृपया ध्यान दें कि यहां समस्या * जीसी विराम नहीं है। - मैं जावा 8 अपडेट 45 का उपयोग करता हूं। व्यवहार विंडोज और लिनक्स के समान है। – malamut

+1

सवाल यह है कि क्या आपका परीक्षण केस आपके वास्तविक वर्कलोड के समान समस्याएं उत्पन्न करता है। लाखों ऑब्जेक्ट्स में एक ही हैशप होल्डिंग होने से हैश मैप के अंदर एक बहुत बड़ी संदर्भ सरणी बन जाएगी, जिसके लिए शायद अपने लिए एक क्षेत्र की आवश्यकता होगी, इस प्रकार हैशपैप तालिका से अधिकांश नोड्स क्रॉस-एरिया में संदर्भों को अधिकतर बनाते हैं, जिसके लिए अधिक आवश्यकता होती है किताब रखने। – the8472

उत्तर

1

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

यह बहुत से पार-क्षेत्र संदर्भ बनाता है, जो जी 1 मध्यम मात्रा में सौदा कर सकता है लेकिन प्रति क्षेत्र लाखों में नहीं।

अत्यधिक इंटरकनेक्टेड क्षेत्रों को जी 1 की हेरिस्टिक्स द्वारा एकत्रित करने के लिए महंगे माना जाता है और इस प्रकार पूरी तरह से कचरा होने पर भी एकत्रित होने की संभावना कम होती है।

क्रॉस-क्षेत्र संदर्भों को कम करने के लिए वस्तुओं को आवंटित करना।

कलात्मक रूप से अपने जीवनकाल को बहुत अधिक विस्तारित नहीं करते हैं (उदाहरण के लिए उन्हें किसी प्रकार के कैश में डालकर) उन्हें युवा पीढ़ी जीसी के दौरान मरने की इजाजत मिलती है, जो पुराने क्षेत्रों की तुलना में इकट्ठा करना बहुत आसान है, जो प्रकृति द्वारा विभिन्न वस्तुओं से संदर्भित वस्तुओं को जमा करते हैं क्षेत्रों।

तो आपके सभी परीक्षण-मामले में जी 1 की क्षेत्र-आधारित प्रकृति के बजाय शत्रुतापूर्ण था।

+0

हां, टेस्ट केस शत्रुतापूर्ण है, लेकिन वास्तविक एप्लिकेशन उसी तरह से विरोधी है, इसलिए परीक्षण केस ने अपना काम किया। :) मैंने इस सत्र को सीखा है कि, जी 1 के साथ, यह सुनिश्चित किया जाना चाहिए कि पार-क्षेत्र-संदर्भों की संख्या दस लाख से अधिक न हो। इसे प्राप्त करने का सबसे आसान तरीका अक्सर यह सुनिश्चित करना होगा कि जीवित वस्तुओं की कुल संख्या बहु-मिलियन रेंज में नहीं बढ़ेगी। – malamut

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