जावा हीप साइज़ की तुलना में बहुत अधिक मेमोरी का उपयोग करता है (या सही ढंग से डॉकर मेमोरी लिमिट का आकार)


118

मेरे आवेदन के लिए, जावा प्रक्रिया द्वारा उपयोग की जाने वाली मेमोरी ढेर के आकार से बहुत अधिक है।

जिस सिस्टम में कंटेनर चल रहे हैं, उसमें मेमोरी की समस्या होने लगती है क्योंकि कंटेनर ढेर के आकार की तुलना में बहुत अधिक मेमोरी ले रहा है।

ढेर का आकार 128 एमबी ( -Xmx128m -Xms128m) पर सेट है जबकि कंटेनर में 1GB तक मेमोरी है। सामान्य स्थिति में, इसे 500 एमबी की आवश्यकता होती है। यदि डॉक कंटेनर में नीचे की सीमा होती है (उदाहरण के लिए mem_limit=mem_limit=400MB) तो प्रक्रिया ओएस के मेमोरी किलर द्वारा समाप्त हो जाती है।

क्या आप बता सकते हैं कि जावा प्रक्रिया ढेर से अधिक मेमोरी का उपयोग क्यों कर रही है? डोकर स्मृति सीमा को सही ढंग से कैसे आकार दें? क्या जावा प्रक्रिया के ऑफ-हाइप मेमोरी फ़ुटप्रिंट को कम करने का एक तरीका है?


मैं JVM में नेटिव मेमोरी ट्रैकिंग से कमांड का उपयोग करके समस्या के बारे में कुछ विवरण इकट्ठा करता हूं ।

होस्ट सिस्टम से, मुझे कंटेनर द्वारा उपयोग की जाने वाली मेमोरी मिलती है।

$ docker stats --no-stream 9afcb62a26c8
CONTAINER ID        NAME                                                                                        CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
9afcb62a26c8        xx-xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.0acbb46bb6fe3ae1b1c99aff3a6073bb7b7ecf85   0.93%               461MiB / 9.744GiB   4.62%               286MB / 7.92MB      157MB / 2.66GB      57

कंटेनर के अंदर से, मुझे प्रक्रिया द्वारा उपयोग की जाने वाली मेमोरी मिलती है।

$ ps -p 71 -o pcpu,rss,size,vsize
%CPU   RSS  SIZE    VSZ
11.2 486040 580860 3814600

$ jcmd 71 VM.native_memory
71:

Native Memory Tracking:

Total: reserved=1631932KB, committed=367400KB
-                 Java Heap (reserved=131072KB, committed=131072KB)
                            (mmap: reserved=131072KB, committed=131072KB) 

-                     Class (reserved=1120142KB, committed=79830KB)
                            (classes #15267)
                            (  instance classes #14230, array classes #1037)
                            (malloc=1934KB #32977) 
                            (mmap: reserved=1118208KB, committed=77896KB) 
                            (  Metadata:   )
                            (    reserved=69632KB, committed=68272KB)
                            (    used=66725KB)
                            (    free=1547KB)
                            (    waste=0KB =0.00%)
                            (  Class space:)
                            (    reserved=1048576KB, committed=9624KB)
                            (    used=8939KB)
                            (    free=685KB)
                            (    waste=0KB =0.00%)

-                    Thread (reserved=24786KB, committed=5294KB)
                            (thread #56)
                            (stack: reserved=24500KB, committed=5008KB)
                            (malloc=198KB #293) 
                            (arena=88KB #110)

-                      Code (reserved=250635KB, committed=45907KB)
                            (malloc=2947KB #13459) 
                            (mmap: reserved=247688KB, committed=42960KB) 

-                        GC (reserved=48091KB, committed=48091KB)
                            (malloc=10439KB #18634) 
                            (mmap: reserved=37652KB, committed=37652KB) 

-                  Compiler (reserved=358KB, committed=358KB)
                            (malloc=249KB #1450) 
                            (arena=109KB #5)

-                  Internal (reserved=1165KB, committed=1165KB)
                            (malloc=1125KB #3363) 
                            (mmap: reserved=40KB, committed=40KB) 

-                     Other (reserved=16696KB, committed=16696KB)
                            (malloc=16696KB #35) 

-                    Symbol (reserved=15277KB, committed=15277KB)
                            (malloc=13543KB #180850) 
                            (arena=1734KB #1)

-    Native Memory Tracking (reserved=4436KB, committed=4436KB)
                            (malloc=378KB #5359) 
                            (tracking overhead=4058KB)

-        Shared class space (reserved=17144KB, committed=17144KB)
                            (mmap: reserved=17144KB, committed=17144KB) 

-               Arena Chunk (reserved=1850KB, committed=1850KB)
                            (malloc=1850KB) 

-                   Logging (reserved=4KB, committed=4KB)
                            (malloc=4KB #179) 

-                 Arguments (reserved=19KB, committed=19KB)
                            (malloc=19KB #512) 

-                    Module (reserved=258KB, committed=258KB)
                            (malloc=258KB #2356) 

$ cat /proc/71/smaps | grep Rss | cut -d: -f2 | tr -d " " | cut -f1 -dk | sort -n | awk '{ sum += $1 } END { print sum }'
491080

एप्लिकेशन जेट्टी / जर्सी / सीडीआई का उपयोग कर एक वेब सर्वर है जो 36 एमबी की एक मोटी दूरी के अंदर बंडल किया गया है।

ओएस और जावा के निम्नलिखित संस्करण का उपयोग किया जाता है (कंटेनर के अंदर)। डॉकर छवि पर आधारित है openjdk:11-jre-slim

$ java -version
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment (build 11+28-Debian-1)
OpenJDK 64-Bit Server VM (build 11+28-Debian-1, mixed mode, sharing)
$ uname -a
Linux service1 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 GNU/Linux

https://gist.github.com/prasanthj/48e7063cac88eb396bc9961fb3149b58


6
यह वह जगह है जहाँ वस्तुओं का आवंटन किया जाता है, हालांकि JVM में साझा लाइब्रेरी, डायरेक्ट मेमोरी बफ़र, थ्रेड स्टैक, जीयूआई घटक, मेटास्टेस सहित कई अन्य मेमोरी क्षेत्र हैं। आपको यह देखने की जरूरत है कि जेवीएम कितना बड़ा हो सकता है और सीमा को इतना अधिक कर सकता है कि आप प्रक्रिया को किसी भी अधिक उपयोग करने के बजाय मर जाएंगे।
पीटर लॉरी

2
ऐसा लग रहा है कि जीसी मेमोरी का भरपूर उपयोग कर रहा है। आप इसके बजाय CMS संग्राहक का उपयोग करने का प्रयास कर सकते हैं। ऐसा लगता है कि ~ 125 एमबी का उपयोग मेटास्पैस + कोड के लिए किया जाता है, हालांकि आपके कोड के आधार को सिकोड़ने के बिना, आप इसे छोटा बनाने में सक्षम होने की संभावना नहीं रखते हैं। प्रतिबद्ध स्थान आपकी सीमा के करीब है इसलिए यह आश्चर्य की बात नहीं है कि यह मारा जाता है।
पीटर लॉरी

कहाँ / कैसे आप -Xms और -Xmx कॉन्फ़िगरेशन सेट करते हैं?
मिक


1
क्या आप कई फ़ाइल-संचालन निष्पादित करते हैं (जैसे गीगाबाइट आकार में फ़ाइलें बनाता है)? यदि ऐसा है, तो आपको पता होना चाहिए कि cgroupsउपयोग की गई मेमोरी में डिस्क-कैश जोड़ता है - भले ही इसे कर्नेल द्वारा संभाला गया हो और यह उपयोगकर्ता प्रोग्राम के लिए अदृश्य है। (माइंड psdocker stats
यू

जवाबों:


205

एक जावा प्रक्रिया द्वारा उपयोग की जाने वाली आभासी मेमोरी सिर्फ जावा हीप से कहीं आगे तक फैली हुई है। आप जानते हैं, जेवीएम में कई उप-प्रजातियां शामिल हैं: कचरा कलेक्टर, क्लास लोडिंग, जेआईटी कंपाइलर आदि, और इन सभी उप प्रणालियों को कार्य करने के लिए कुछ निश्चित मात्रा में रैम की आवश्यकता होती है।

JVM केवल RAM का उपभोक्ता नहीं है। देशी पुस्तकालय (मानक जावा क्लास लाइब्रेरी सहित) भी देशी मेमोरी आवंटित कर सकते हैं। और यह नेटिव मेमोरी ट्रैकिंग के लिए भी दिखाई नहीं देगा। जावा एप्लिकेशन स्वयं भी डायरेक्ट बाइटबफर्स ​​के माध्यम से ऑफ-हीप मेमोरी का उपयोग कर सकता है।

तो जावा प्रोसेस में मेमोरी क्या लगती है?

जेवीएम पार्ट्स (ज्यादातर मूल निवासी मेमोरी ट्रैकिंग द्वारा दिखाए गए)

  1. जावा हीप

    सबसे स्पष्ट हिस्सा है। यह वह जगह है जहाँ जावा ऑब्जेक्ट रहते हैं। हीप -Xmxमेमोरी की मात्रा तक ले जाता है ।

  2. कचरा इकट्ठा करने वाला

    जीसी संरचनाओं और एल्गोरिदम को ढेर प्रबंधन के लिए अतिरिक्त मेमोरी की आवश्यकता होती है। ये संरचनाएं हैं मार्क बिटमैप, मार्क स्टैक (ऑब्जेक्ट ग्राफ को ट्रैवर्स करने के लिए), याद किए गए सेट (अंतर-क्षेत्र संदर्भों को रिकॉर्ड करने के लिए) और अन्य। उनमें से कुछ सीधे ट्यून करने योग्य हैं, उदाहरण के लिए -XX:MarkStackSizeMax, अन्य ढेर लेआउट पर निर्भर करते हैं, उदाहरण के लिए बड़े जी 1 क्षेत्र ( -XX:G1HeapRegionSize) हैं, छोटे सेट याद किए जाते हैं।

    जीसी एल्गोरिदम के बीच जीसी मेमोरी ओवरहेड भिन्न होता है। -XX:+UseSerialGCऔर -XX:+UseShenandoahGCसबसे छोटा ओवरहेड है। G1 या CMS कुल ढेर आकार का लगभग 10% आसानी से उपयोग कर सकते हैं।

  3. कोड कैश

    इसमें गतिशील रूप से उत्पन्न कोड शामिल हैं: JIT- संकलित तरीके, दुभाषिया और रन-टाइम स्टब्स। इसका आकार -XX:ReservedCodeCacheSize(240M डिफ़ॉल्ट रूप से) द्वारा सीमित है । -XX:-TieredCompilationसंकलित कोड की मात्रा को कम करने के लिए बंद करें और इस प्रकार कोड कैश का उपयोग करें।

  4. संकलक

    JIT कंपाइलर को भी अपना काम करने के लिए मेमोरी की आवश्यकता होती है। यह फिर से Tiered Compilation को बंद करके या संकलक थ्रेड्स की संख्या को घटाकर कम किया जा सकता है -XX:CICompilerCount:।

  5. क्लास लोडिंग

    क्लास मेटाडेटा (विधि बाइटकोड, प्रतीक, निरंतर पूल, एनोटेशन आदि) ऑफ-ढेर क्षेत्र में स्टोर किया जाता है जिसे रास्पैस कहा जाता है। अधिक कक्षाएं भरी हुई हैं - अधिक मेटास्टेस का उपयोग किया जाता है। कुल उपयोग सीमित हो सकता है -XX:MaxMetaspaceSize(डिफ़ॉल्ट रूप से असीमित) और -XX:CompressedClassSpaceSize(डिफ़ॉल्ट रूप से 1G)।

  6. प्रतीक टेबल

    JVM के दो मुख्य हैशटैब: प्रतीक तालिका में नाम, हस्ताक्षर, पहचानकर्ता आदि होते हैं और स्ट्रिंग तालिका में आंतरिक तार के संदर्भ होते हैं। यदि मूल मेमोरी ट्रैकिंग स्ट्रिंग तालिका द्वारा महत्वपूर्ण मेमोरी उपयोग का संकेत देती है, तो संभवतः इसका अर्थ है कि एप्लिकेशन अत्यधिक कॉल करता है String.intern

  7. धागे

    रैम लेने के लिए थ्रेड स्टैक भी जिम्मेदार हैं। स्टैक आकार द्वारा नियंत्रित किया जाता है -Xss। डिफ़ॉल्ट 1M प्रति थ्रेड है, लेकिन सौभाग्य से चीजें इतनी बुरी नहीं हैं। OS मेमोरी पृष्ठों को पहले उपयोग के आधार पर आवंटित करता है, इसलिए वास्तविक मेमोरी का उपयोग बहुत कम होगा (आमतौर पर 80-200 केबी प्रति स्टैक स्टैक)। मैंने यह लिखने के लिए एक स्क्रिप्ट लिखी थी कि जावा थ्रेड स्टैक में RSS का कितना हिस्सा है।

    अन्य जेवीएम भाग हैं जो देशी मेमोरी आवंटित करते हैं, लेकिन वे आम तौर पर कुल मेमोरी खपत में बड़ी भूमिका नहीं निभाते हैं।

प्रत्यक्ष बफ़र्स

कोई एप्लिकेशन कॉल करके स्पष्ट रूप से ऑफ-हीप मेमोरी का अनुरोध कर सकता है ByteBuffer.allocateDirect। डिफ़ॉल्ट ऑफ-हीप सीमा के बराबर है -Xmx, लेकिन इसके साथ ओवरराइड किया जा सकता है -XX:MaxDirectMemorySize। डायरेक्ट बाइटबफर्स Otherएनएमटी आउटपुट के अनुभाग में शामिल हैं (या Internalजेडीके 11 से पहले)।

उपयोग की गई सीधी मेमोरी की मात्रा JMX के माध्यम से दिखाई देती है, जैसे JConsole या Java Mission Control में:

बफ़रपूल एमबीएन

प्रत्यक्ष बाइटफर्फ़र्स के अलावा MappedByteBuffers- एक प्रक्रिया की आभासी मेमोरी में मैप की गई फाइलें हो सकती हैं। NMT उन्हें ट्रैक नहीं करता है, हालाँकि, MappedByteBuffers भौतिक मेमोरी भी ले सकते हैं। और यह सीमित करने का कोई सरल तरीका नहीं है कि वे कितना ले सकते हैं। आप प्रक्रिया मेमोरी मैप को देखकर केवल वास्तविक उपयोग देख सकते हैं:pmap -x <pid>

Address           Kbytes    RSS    Dirty Mode  Mapping
...
00007f2b3e557000   39592   32956       0 r--s- some-file-17405-Index.db
00007f2b40c01000   39600   33092       0 r--s- some-file-17404-Index.db
                           ^^^^^               ^^^^^^^^^^^^^^^^^^^^^^^^

देशी पुस्तकालय

द्वारा लोड किया गया जेएनआई कोड System.loadLibraryजेवीएम की ओर से बिना किसी नियंत्रण के जितना चाहे उतना ऑफ-मेमोरी मेमोरी आवंटित कर सकता है। यह मानक जावा क्लास लाइब्रेरी की भी चिंता करता है। विशेष रूप से, अस्पष्ट जावा संसाधन मूल मेमोरी रिसाव का स्रोत बन सकते हैं। विशिष्ट उदाहरण हैं ZipInputStreamया DirectoryStream

जेवीएमटीआई एजेंट, विशेष रूप से, jdwpडिबगिंग एजेंट - स्मृति की अत्यधिक खपत का कारण भी बन सकते हैं।

यह उत्तर बताता है कि कैसे async-profiler के साथ देशी मेमोरी आवंटन को प्रोफाइल करना है ।

आवंटन मुद्दों

एक प्रक्रिया आम तौर पर देशी मेमोरी को सीधे ओएस ( mmapसिस्टम कॉल द्वारा) या mallocमानक लीबक एलोकेटर का उपयोग करके अनुरोध करती है । बदले में, mallocओएस का उपयोग करके मेमोरी के बड़े हिस्से का अनुरोध mmapकरता है, और फिर इन आवंटन को अपने स्वयं के आवंटन एल्गोरिथ्म के अनुसार प्रबंधित करता है। समस्या यह है - इस एल्गोरिथ्म में विखंडन और अत्यधिक आभासी मेमोरी का उपयोग हो सकता है

jemalloc, एक वैकल्पिक आवंटनकर्ता, अक्सर नियमित लिबास की तुलना में अधिक स्मार्ट दिखाई देता है malloc, इसलिए स्विच करने से jemallocमुफ्त में छोटे पदचिह्न प्राप्त हो सकते हैं।

निष्कर्ष

जावा प्रक्रिया के पूर्ण मेमोरी उपयोग का अनुमान लगाने का कोई गारंटी तरीका नहीं है, क्योंकि विचार करने के लिए बहुत सारे कारक हैं।

Total memory = Heap + Code Cache + Metaspace + Symbol tables +
               Other JVM structures + Thread stacks +
               Direct buffers + Mapped files +
               Native Libraries + Malloc overhead + ...

जेवीएम के झंडे द्वारा कुछ मेमोरी क्षेत्रों (जैसे कोड कैश) को सिकोड़ना या सीमित करना संभव है, लेकिन कई अन्य सभी जेवीएम नियंत्रण से बाहर हैं।

डॉकर सीमा निर्धारित करने का एक संभावित तरीका प्रक्रिया की "सामान्य" स्थिति में वास्तविक मेमोरी उपयोग को देखना होगा। जावा मेमोरी खपत के साथ मुद्दों की जांच के लिए उपकरण और तकनीकें हैं: मूल मेमोरी ट्रैकिंग , pmap , jemalloc , async-profiler

अपडेट करें

यहाँ एक जावा प्रोसेस की मेरी प्रस्तुति मेमोरी फुटप्रिंट की रिकॉर्डिंग है ।

इस वीडियो में, मैं चर्चा करता हूं कि एक जावा प्रक्रिया में मेमोरी का उपभोग कैसे किया जा सकता है, कुछ मेमोरी क्षेत्रों के आकार की निगरानी और संयम कैसे किया जा सकता है, और एक जावा एप्लिकेशन में देशी मेमोरी लीक को कैसे प्रोफाइल किया जाए।


1
Jdk7 के बाद से ढेर में नजरबंद नहीं हैं? ( Bugs.java.com/bugdatabase/view_bug.do?bug_id=6962931 ) - शायद मैं गलत हूं।
j-keck

5
@ j-keck स्ट्रिंग ऑब्जेक्ट्स ढेर में हैं, लेकिन हैशटेबल (बाल्टी और संदर्भ और हैश कोड वाली प्रविष्टियाँ) ऑफ-हीप मेमोरी में है। मैंने वाक्य को और अधिक सटीक होने के लिए पुन: प्रस्तुत किया। इशारा करने के लिए धन्यवाद।
अपंगिन

इसे जोड़ने के लिए, भले ही आप गैर-प्रत्यक्ष बाइटबफर्स ​​का उपयोग करते हों, जेवीएम देशी मेमोरी में अस्थायी प्रत्यक्ष बफ़र्स आवंटित करेगा जिसमें कोई मेमोरी सीमा नहीं है। सी एफ evanjones.ca/java-bytebuffer-leak.html
Cpt। सेनकफस

16

https://developers.redhat.com/blog/2017/04/04/openjdk-and-containers/ :

जब मैं निर्दिष्ट करता हूं तो यह क्यों होता है -Xmx = 1g मेरा JVM 1GB से अधिक मेमोरी का उपयोग करता है?

निर्दिष्ट -Xmx = 1g JVM को 1gb ढेर आवंटित करने के लिए कह रहा है। यह JVM को उसकी संपूर्ण मेमोरी उपयोग को 1gb तक सीमित करने के लिए नहीं कह रहा है। कार्ड टेबल, कोड कैश और अन्य सभी प्रकार के ढेर डेटा संरचनाएं हैं। कुल मेमोरी उपयोग को निर्दिष्ट करने के लिए आपके द्वारा उपयोग किया जाने वाला पैरामीटर -XX: MaxRAM है। ध्यान रखें कि -XX: MaxRam = 500 मीटर पर आपका ढेर लगभग 250mb होगा।

जावा होस्ट मेमोरी साइज देखता है और यह किसी भी कंटेनर मेमोरी लिमिट के बारे में नहीं जानता है। यह मेमोरी प्रेशर नहीं बनाता है, इसलिए GC को उपयोग की गई मेमोरी को रिलीज़ करने की भी आवश्यकता नहीं है। मुझे आशा है कि XX:MaxRAMआप स्मृति पदचिह्न को कम करने में मदद करेंगे। अंततः, आप जीसी विन्यास ठीक कर सकते हैं ( -XX:MinHeapFreeRatio, -XX:MaxHeapFreeRatio, ...)


मेमोरी मेट्रिक्स कई प्रकार के होते हैं। डॉकर को RSS मेमोरी साइज़ की रिपोर्टिंग लगती है, जो कि रिपोर्ट की गई "प्रतिबद्ध" मेमोरी से अलग हो सकती है jcmd(Docker के पुराने संस्करण RSS + कैश को मेमोरी यूज़ के रूप में रिपोर्ट करते हैं)। अच्छी चर्चा और लिंक: डॉकटर कंटेनर में चलने वाले JVM के लिए रेजिडेंट सेट साइज़ (RSS) और जावा टोटल मेमोरी (NMT) के बीच अंतर

(RSS) मेमोरी को कंटेनर में कुछ अन्य उपयोगिताओं द्वारा भी खाया जा सकता है - शेल, प्रोसेस मैनेजर, ... हमें नहीं पता कि कंटेनर में और क्या चल रहा है और आप कंटेनर में प्रक्रिया कैसे शुरू करते हैं।


यह वास्तव में के साथ बेहतर है -XX:MaxRam। मुझे लगता है कि यह अभी भी अधिकतम परिभाषित की तुलना में अधिक उपयोग कर रहा है लेकिन यह बेहतर है, धन्यवाद!
निकोलस हेन्नेक्स

हो सकता है कि आपको वास्तव में इस जावा उदाहरण के लिए अधिक मेमोरी की आवश्यकता हो। 15267 कक्षाएं, 56 धागे हैं।
जन गरज

1
यहां अधिक विवरण, जावा तर्क -Xmx128m -Xms128m -Xss228k -XX:MaxRAM=256m -XX:+UseSerialGC, उत्पादन Docker 428.5MiB / 600MiBऔर हैं jcmd 58 VM.native_memory -> Native Memory Tracking: Total: reserved=1571296KB, committed=314316KBJVM को लगभग 300MB लग रहा है जबकि कंटेनर को 430MB की आवश्यकता है। JVM रिपोर्टिंग और OS रिपोर्टिंग के बीच 130MB कहाँ हैं?
निकोलस हेन्नेको

1
आरएसएस मेमोरी के बारे में जानकारी / लिंक जोड़ा गया।
Jan Garaj

बशर्ते आरएसएस जावा प्रक्रिया के लिए कंटेनर के अंदर से है, केवल जावा प्रक्रिया के ps -p 71 -o pcpu,rss,size,vsizeसाथ ही पीआईडी ​​71 है। वास्तव -XX:MaxRamमें मदद नहीं कर रहा था लेकिन आपके द्वारा प्रदान की गई लिंक धारावाहिक जीसी के साथ मदद करती है।
निकोलस हेन्नेको

8

टी एल; डॉ

मेमोरी का विस्तृत उपयोग मूल मेमोरी ट्रैकिंग (NMT) विवरण (मुख्य रूप से कोड मेटाडेटा और कचरा संग्रहकर्ता) द्वारा प्रदान किया जाता है। इसके अलावा, Java कंपाइलर और ऑप्टिमाइज़र C1 / C2 सारांश में रिपोर्ट नहीं की गई मेमोरी का उपभोग करते हैं।

JVM झंडे (लेकिन प्रभाव है) का उपयोग करके मेमोरी फ़ुटप्रिंट को कम किया जा सकता है।

डॉकटर कंटेनर साइजिंग को अपेक्षित लोड के साथ परीक्षण के माध्यम से किया जाना चाहिए।


प्रत्येक घटक के लिए विस्तार

साझा वर्ग अंतरिक्ष एक कंटेनर के अंदर निष्क्रिय किया जा सकता के बाद से कक्षाएं एक और JVM प्रक्रिया के द्वारा साझा नहीं किया जाएगा। निम्नलिखित ध्वज का उपयोग किया जा सकता है। यह साझा वर्ग स्थान (17MB) को हटा देगा।

-Xshare:off

कचरा कलेक्टर धारावाहिक कचरा कलेक्ट प्रसंस्करण के दौरान लंबे समय तक ठहराव समय की कीमत पर एक न्यूनतम स्मृति पदचिह्न (देखें है एक तस्वीर में जी सी के बीच अलेक्सी Shipilëv तुलना )। इसे निम्न ध्वज के साथ सक्षम किया जा सकता है। यह उपयोग किए जाने वाले GC स्थान (48MB) तक बचा सकता है।

-XX:+UseSerialGC

सी 2 संकलक का अनुकूलन करने के लिए या नहीं एक विधि तय करने के लिए इस्तेमाल की रूपरेखा डेटा को कम करने के लिए निम्न ध्वज के साथ निष्क्रिय किया जा सकता।

-XX:+TieredCompilation -XX:TieredStopAtLevel=1

कोड स्थान 20MB से कम हो जाता है। इसके अलावा, JVM के बाहर की मेमोरी 80MB (NMT स्पेस और RSS स्पेस के बीच का अंतर) कम हो जाती है। अनुकूलन करने वाले कंपाइलर C2 को 100MB की आवश्यकता होती है।

C1 और C2 compilers निम्नलिखित ध्वज के साथ निष्क्रिय किया जा सकता।

-Xint

जेवीएम के बाहर की मेमोरी अब कुल प्रतिबद्ध जगह से कम है। कोड स्थान 43MB से कम हो जाता है। खबरदार, यह आवेदन के प्रदर्शन पर एक बड़ा प्रभाव है। C1 और C2 कंपाइलर को अक्षम करने से 170 एमबी से उपयोग की जाने वाली मेमोरी कम हो जाती है।

का उपयोग करते हुए ग्राल वीएम संकलक थोड़ा छोटे स्मृति पदचिह्न को (सी 2 के प्रतिस्थापन) की ओर जाता है। यह 20MB कोड मेमोरी स्पेस को बढ़ाता है और JVM मेमोरी के बाहर से 60MB कम हो जाता है।

जेवीएम के लिए लेख जावा मेमोरी मैनेजमेंट कुछ प्रासंगिक जानकारी अलग-अलग मेमोरी स्पेस प्रदान करता है। Oracle नेटिव मेमोरी ट्रैकिंग प्रलेखन में कुछ विवरण प्रदान करता है । उन्नत संकलन नीति में संकलन स्तर के बारे में अधिक जानकारी और अक्षम C2 में कारक 5 से कोड कैश आकार को कम करें । पर कुछ विवरण क्यों एक JVM रिपोर्ट अधिक प्रतिबद्ध स्मृति लिनक्स से की प्रक्रिया निवासी सेट आकार करता है? जब दोनों संकलक अक्षम हो जाते हैं।


-1

जावा को बहुत अधिक मेमोरी की आवश्यकता होती है। JVM को चलाने के लिए बहुत मेमोरी की आवश्यकता होती है। ढेर वह मेमोरी है जो वर्चुअल मशीन के अंदर उपलब्ध है, आपके एप्लिकेशन के लिए उपलब्ध है। क्योंकि JVM एक बड़ा बंडल है जो सभी अच्छाइयों से भरा हुआ है और इसे लोड करने में बहुत अधिक मेमोरी लगती है।

जावा 9 से शुरू होने पर आपके पास प्रोजेक्ट आरा नामक कुछ है , जो कि जावा ऐप शुरू करने के साथ-साथ आपके द्वारा उपयोग की जाने वाली मेमोरी को कम कर सकता है (शुरुआत के समय के साथ)। आवश्यक पहेली को कम करने के लिए प्रोजेक्ट आरा और एक नया मॉड्यूल सिस्टम जरूरी नहीं बनाया गया था, लेकिन अगर यह महत्वपूर्ण है तो आप एक कोशिश दे सकते हैं।

आप इस उदाहरण पर एक नज़र डाल सकते हैं: https://steveperkins.com/using-java-9-modularization-to-ship-zero-d dependency-native-apps/ । मॉड्यूल सिस्टम का उपयोग करके इसका परिणाम 21MB (JRE एम्बेड के साथ) के CLI अनुप्रयोग में हुआ। JRE को 200mb से अधिक का समय लगता है। आवेदन कम होने पर कम आवंटित मेमोरी में अनुवाद करना चाहिए (बहुत अधिक अप्रयुक्त जेआरई कक्षाएं अब लोड नहीं होंगी)।

यहाँ एक और अच्छा ट्यूटोरियल है: https://www.baeldung.com/project-jư-java-modularity

यदि आप इसके साथ समय नहीं बिताना चाहते हैं तो आप अधिक मेमोरी आवंटित कर सकते हैं। कभी-कभी यह सबसे अच्छा होता है।


उपयोग करना jlinkकाफी प्रतिबंधक है क्योंकि इसके लिए आवेदन को संशोधित करने की आवश्यकता होती है। स्वचालित मॉड्यूल का समर्थन नहीं किया जाता है, इसलिए वहां जाने का कोई आसान तरीका नहीं है।
निकोलस हेन्को

-1

डोकर स्मृति सीमा को सही ढंग से कैसे आकार दें? एप्लिकेशन को कुछ समय के लिए मॉनिटर करके चेक करें। कंटेनर की मेमोरी को सीमित करने के लिए -m का उपयोग करने का प्रयास करें, - docker run कमांड के लिए -Memory बाइट्स विकल्प - या कुछ समतुल्य यदि आप अन्यथा जैसे चल रहे हैं

docker run -d --name my-container --memory 500m <iamge-name>

अन्य सवालों के जवाब नहीं दे सकते।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.