2013-03-20 8 views
5

manual page ने मुझे इतना बताया और इसके माध्यम से मुझे "ग्लिब" के मेमोरी प्रबंधन के बहुत सारे पृष्ठभूमि ज्ञान पता है।"malloc_trim (0)" वास्तव में क्या मतलब है?

लेकिन मैं अभी भी उलझन में हूं। क्या "malloc_trim (0)" (पैरामीटर के रूप में शून्य नोट करें) मतलब (1.) "ढेर" अनुभाग में सभी मेमोरी ओएस पर वापस आ जाएगी? या (2.) ढेर के शीर्ष क्षेत्र के सभी "अप्रयुक्त" मेमोरी को ओएस में वापस कर दिया जाएगा?

अगर जवाब (1.) है, अगर ढेर में अभी भी प्रयोग किया स्मृति क्या? यदि ढेर ने जगहों पर कहीं भी मातृभाषा का उपयोग किया है, तो क्या उन्हें समाप्त कर दिया जाएगा, या समारोह सफलतापूर्वक निष्पादित नहीं होगा?

जबकि अगर जवाब (2.), क्या उन "छेद" बल्कि ढेर में शीर्ष से स्थानों पर के बारे में? वे अब अप्रयुक्त स्मृति कर रहे हैं, है, लेकिन ढेर के शीर्ष सबसे क्षेत्र अब भी है इस्तेमाल किया, क्या यह कॉलिंग कुशलतापूर्वक काम करेगा?

धन्यवाद।

उत्तर

4

malloc_trim के लिए आदमी पेज यह मुफ़्त स्मृति जारी करता है, इसलिए यदि कोई ढेर में स्मृति आवंटित किया जाता है, यह पूरे ढेर जारी नहीं करेगा कहते हैं। पैरामीटर वहां है यदि आपको पता है कि आपको अभी भी स्मृति की एक निश्चित मात्रा की आवश्यकता होगी, इसलिए इससे अधिक मुक्त होने से ग्लिबैक को बाद में अनावश्यक काम करना होगा।

छेद के लिए, यह स्मृति प्रबंधन और ओएस को स्मृति लौटने के साथ एक मानक समस्या है। प्राथमिक निम्न स्तर के ढेर प्रबंधन कार्यक्रम के लिए उपलब्ध brk और sbrk है, और सभी वे क्या कर सकते हैं बढ़ाने या शीर्ष बदलकर ढेर क्षेत्र हटना है। इसलिए ऑपरेटिंग सिस्टम में छेद वापस करने का कोई रास्ता नहीं है; एक बार कार्यक्रम ने अधिक ढेर आवंटित करने के लिए sbrk कहा है, तो उस स्थान को केवल तभी वापस किया जा सकता है जब उस स्थान का शीर्ष मुक्त हो और उसे वापस सौंप दिया जा सके।

नोट वहाँ अन्य, अधिक जटिल (अनाम mmap साथ, उदाहरण के लिए) स्मृति को आबंटित करने के तरीके, जो sbrk आधारित आवंटन की तुलना में अलग बाधाओं हो सकता है कि।

malloc_trim की
+0

अब ओएस के लिए वापस ढेर के बीच में छेद लौटने की विधि है http://code.metager.de/source/xref/gnu/glibc/malloc/malloc.C# 4535 'mtrim (mstate av, size_t पैड) ... __madvise (paligned_mem, आकार और ~ psm1, MADV_DONTNEED);'। इस तरह के झंडे के साथ 'पागलपन' पृष्ठ के लिए आवश्यक पृष्ठों को चिह्नित करता है, ओएस उनसे डेटा नष्ट कर सकता है और भौतिक स्थान को अनैप कर सकता है; पृष्ठ की अगली पहुंच वर्चुअल पेज को भौतिक स्थान पर रीमेप करने के लिए पेजफॉल्ट उत्पन्न कर सकती है। – osgx

+0

कोड https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc 68631c8eb92ff38d9da1ae34f6aa048539b199cc "(एमटीआरआईएम) में जोड़ा गया था: इसके अतिरिक्त सभी निःशुल्क ब्लॉक पर पुन: सक्रिय करें और उन सभी ब्लॉकों के लिए मेमोरीज़ को मुफ्त मेमोरी में उपयोग करें जिनमें कम से कम एक मेमोरी पेज है। " - \t Ulrich Drepper 16 दिसंबर 2007 (glibc 2.9) – osgx

0

मैन पेज यहाँ हामी भर दी थी: https://github.com/mkerrisk/man-pages/blob/master/man3/malloc_trim.3 और के रूप में मैं समझता हूँ, यह आदमी पृष्ठों परियोजना मेंटेनर द्वारा, kerrisk 2012 में खरोंच से लिखा गया था: https://github.com/mkerrisk/man-pages/commit/a15b0e60b297e29c825b7417582a33e6ca26bf65

जैसा कि मैंने यह कर सकते हैं grep the glibc's git, there are no man pages in the glibc है, और कोई malloc_trim मैनपेज के लिए प्रतिबद्ध इस पैच को दस्तावेज करने के लिए। https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c malloc/malloc.c से malloc_trim टिप्पणी नहीं है:

Additional functions: 
malloc_trim(size_t pad); 
609 /* 
610 malloc_trim(size_t pad); 
611 
612 If possible, gives memory back to the system (via negative 
613 arguments to sbrk) if there is unused memory at the `high' end of 
614 the malloc pool. You can call this after freeing large blocks of 
615 memory to potentially reduce the system-level memory requirements 
616 of a program. However, it cannot guarantee to reduce memory. Under 
617 some allocation patterns, some large free blocks of memory will be 
618 locked between two used chunks, so they cannot be given back to 
619 the system. 
620 
621 The `pad' argument to malloc_trim represents the amount of free 
622 trailing space to leave untrimmed. If this argument is zero, 
623 only the minimum amount of memory to maintain internal data 
624 structures will be left (one page or less). Non-zero arguments 
625 can be supplied to maintain enough trailing space to service 
626 future expected allocations without having to re-obtain memory 
627 from the system. 
628 
629 Malloc_trim returns 1 if it actually released any memory, else 0. 
630 On systems that do not support "negative sbrks", it will always 
631 return 0. 
632 */ 
633 int  __malloc_trim(size_t); 
634 

हिस्सा के मध्य से मुक्त malloc में पाठ के रूप में दर्ज नहीं किया गया है/malloc.c glibc malloc का सबसे अच्छा और केवल प्रलेखन इसके स्रोत कोड है और मैन-पेज प्रोजेक्ट में दस्तावेज नहीं किया गया है। 2012 से मैन पेज फ़ंक्शन का पहला मैन पेज हो सकता है, जिसे ग्लिब के लेखकों द्वारा नहीं लिखा गया है। glibc की जानकारी पेज केवल 128 KB की M_TRIM_THRESHOLD का उल्लेख है: https://www.gnu.org/software/libc/manual/html_node/Malloc-Tunable-Parameters.html#Malloc-Tunable-Parameters और malloc_trim समारोह https://www.gnu.org/software/libc/manual/html_node/Summary-of-Malloc.html#Summary-of-Malloc सूची नहीं है (और यह भी दस्तावेज़ memusage/memusagestat/libmemusage.so नहीं है)।

दिसंबर 2007 में हुई थी अलरिक ड्रेपपर द्वारा https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc प्रतिबद्ध (यह glibc 2 का हिस्सा है।9 और नवीन) जो mtrim कार्यान्वयन बदल (लेकिन यह किसी भी दस्तावेज या आदमी पेज परिवर्तन नहीं किया के रूप में वहाँ glibc में कोई आदमी पृष्ठों) कर रहे हैं:

  • malloc/malloc.c (public_mTRIm): सब कुछ खत्म हो दोहराएं Arenas और कॉल

उन सभी के लिए एमटीआरआईएम। (एमटीआरआईएम): इसके अतिरिक्त सभी फ्री ब्लॉकों पर पुन: प्रयास करें और कम से कम एक मेमोरी पेज वाले सभी ब्लॉकों के लिए मेमोरी का उपयोग करें।

मात्रा का उपयोग न किए गए भागों (कहीं भी, बीच में हिस्सा भी शामिल है), पृष्ठ आकार पर गठबंधन और पेज MADV_DONTNEEDhttps://sourceware.org/git/?p=glibc.git;a=blobdiff;f=malloc/malloc.c;h=c54c203cbf1f024e72493546221305b4fd5729b7;hp=1e716089a2b976d120c304ad75dd95c63737ad75;hb=68631c8eb92ff38d9da1ae34f6aa048539b199cc;hpb=52386be756e113f20502f181d780aecc38cbb66a

 INTERNAL_SIZE_T size = chunksize (p); 

     if (size > psm1 + sizeof (struct malloc_chunk)) 
     { 
      /* See whether the chunk contains at least one unused page. */ 
      char *paligned_mem = (char *) (((uintptr_t) p 
              + sizeof (struct malloc_chunk) 
              + psm1) & ~psm1); 

      assert ((char *) chunk2mem (p) + 4 * SIZE_SZ <= paligned_mem); 
      assert ((char *) p + size > paligned_mem); 

      /* This is the size we could potentially free. */ 
      size -= paligned_mem - (char *) p; 

      if (size > psm1) 
       madvise (paligned_mem, size & ~psm1, MADV_DONTNEED); 
     } 

के रूप में चिह्नित किया जा सकता है और अधिक से अधिक आकार के होने इस कुल दो प्रयोगों में से एक है http://code.metager.de/source/search?q=MADV_DONTNEED&path=%2Fgnu%2Fglibc%2Fmalloc%2F&project=gnu

H A D arena.c 643 __madvise ((char *) h + new_size, diff, MADV_DONTNEED); 
H A D malloc.c 4535 __madvise (paligned_mem, size & ~psm1, MADV_DONTNEED); 
: अब glibc में MADV_DONTNEED, ढेर के शीर्ष भाग ( shrink_heap) और के लिए एक साथ madvise के अन्य किसी भी हिस्सा ( mtrim) का अंकन है

हम इस सरल सी कार्यक्रम (test_malloc_trim.c) और strace/ltrace साथ malloc_trim परीक्षण कर सकते हैं:

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <malloc.h> 

int main() 
{ 
    int *m1,*m2,*m3,*m4; 
    printf("%s\n","Test started"); 
    m1=(int*)malloc(20000); 
    m2=(int*)malloc(40000); 
    m3=(int*)malloc(80000); 
    m4=(int*)malloc(10000); 
    // check that all arrays are allocated on the heap and not with mmap 
    printf("1:%p 2:%p 3:%p 4:%p\n", m1, m2, m3, m4); 
    // free 40000 bytes in the middle 
    free(m2); 
    // call trim (same result with 2000 or 2000000 argument) 
    malloc_trim(0); 
    // call some syscall to find this point in the strace output 
    sleep(1); 
    free(m1); 
    free(m3); 
    free(m4); 
    // malloc_stats(); malloc_info(0, stdout); 
    return 0; 
} 

gcc test_malloc_trim.c -o test_malloc_trim, strace ./test_malloc_trim

write(1, "Test started\n", 13Test started 
)   = 13 
brk(0)         = 0xcca000 
brk(0xcef000)       = 0xcef000 
write(1, "1:0xcca010 2:0xccee40 3:0xcd8a90"..., 441:0xcca010 2:0xccee40 3:0xcd8a90 4:0xcec320 
) = 44 
madvise(0xccf000, 36864, MADV_DONTNEED) = 0 
... 
nanosleep({1, 0}, 0x7ffffafbfff0)  = 0 
brk(0xceb000)       = 0xceb000 

तो, वहाँ madviseMADV_DONTNEED साथ malloc_trim(0) के बाद 9 पृष्ठों के लिए था कॉल, जब ढेर के बीच में 40008 बाइट्स का छेद था। MADV_DONTNEED (और कभी कभी MADV_FREE):

+0

मैन पेजों और अन्य दस्तावेजों पर जीएनयू जैसी परियोजना रखरखाव की विशिष्ट आधिकारिक स्थिति: https://sourceware.org/bugzilla/show_bug.cgi?id=2531#c4 "Ulrich Drepper 2006-05-01 मैन पेज ग्लिब में बनाए रखा नहीं है। इसे मैन पेज रखरखाव को बताएं। " – osgx

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