perl memory use
play

Perl Memory Use Tim Bunce @ OSCON July 2012 1 Scope of the talk... - PowerPoint PPT Presentation

Perl Memory Use Tim Bunce @ OSCON July 2012 1 Scope of the talk... Not really "profiling" No leak detection No VM, page mapping, MMU, TLB, threads etc Linux focus Almost no copy-on-write No cats 2 Goals


  1. Perl Memory Use Tim Bunce @ OSCON July 2012 1

  2. Scope of the talk... ✦ Not really "profiling" ✦ No leak detection ✦ No VM, page mapping, MMU, TLB, threads etc ✦ Linux focus ✦ Almost no copy-on-write ✦ No cats 2

  3. Goals ✦ Give you a top-to-bottom overview ✦ Identify the key issues and complications ✦ Show you useful tools along the way ✦ Future plans 3

  4. Ouch! $ perl some_script.pl Out of memory! $ $ perl some_script.pl Killed. $ $ perl some_script.pl $ Someone shouts: "Hey! My process has been killed!" $ perl some_script.pl [later] "Umm, what's taking so long?" 4

  5. Process Memory 5

  6. C Program Code int main(...) { ... } Read-only Data eg “String constants” Read-write Data un/initialized variables Heap (not to scale!) Shared Lib Code \\ Shared Lib R/O Data repeated for each lib Shared Lib R/W Data // C Stack (not the perl stack) System 6

  7. $ perl -e 'system(" cat /proc/$$/stat ")' 4752 (perl) S 4686 4752 4686 34816 4752 4202496 536 0 0 0 0 0 0 0 20 0 1 0 62673440 123121664 440 18446744073709551615 4194304 4198212 140735314078128 140735314077056 140645336670206 0 0 134 0 18446744071579305831 0 0 17 10 0 0 0 0 0 0 0 0 0 0 4752 111 111 111 $ perl -e 'system(" cat /proc/$$/statm ")' 30059 441 346 1 0 160 0 $ perl -e 'system(" ps -p $$ -o vsz,rsz,sz,size ")' VSZ RSZ SZ SZ 120236 1764 30059 640 $ perl -e 'system(" top -b -n1 -p $$ ")' ... PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 13063 tim 20 0 117m 1764 1384 S 0.0 0.1 0:00.00 perl $ perl -e 'system(" cat /proc/$$/status ")' ... VmPeak: � 120236 kB VmSize: � 120236 kB <- total (code, libs, stack, heap etc.) VmHWM: � 1760 kB VmRSS: � 1760 kB <- how much of the total is resident in physical memory VmData: � 548 kB <- data (heap) VmStk: � 92 kB <- stack VmExe: � 4 kB <- code VmLib: � 4220 kB <- libs, including libperl.so VmPTE: � 84 kB VmPTD: � 28 kB VmSwap: � 0 kB Further info on unix.stackexchange.com ... 7

  8. $ perl -e 'system(" cat /proc/$$/maps ")' address perms ... pathname 00400000-00401000 r-xp ... /.../perl-5.NN.N/bin/perl 00601000-00602000 rw-p ... /.../perl-5.NN.N/bin/perl 0087f000-008c1000 rw-p ... [heap] 7f858cba1000-7f8592a32000 r--p ... /usr/lib/locale/locale-archive-rpm 7f8592c94000-7f8592e1a000 r-xp ... /lib64/libc-2.12.so 7f8592e1a000-7f859301a000 ---p ... /lib64/libc-2.12.so 7f859301a000-7f859301e000 r--p ... /lib64/libc-2.12.so 7f859301e000-7f859301f000 rw-p ... /lib64/libc-2.12.so 7f859301f000-7f8593024000 rw-p ... ...other libs... 7f8593d1b000-7f8593e7c000 r-xp ... /.../lib/5.NN.N/x86_64-linux/CORE/libperl.so 7f8593e7c000-7f859407c000 ---p ... /.../lib/5.NN.N/x86_64-linux/CORE/libperl.so 7f859407c000-7f8594085000 rw-p ... /.../lib/5.NN.N/x86_64-linux/CORE/libperl.so 7f85942a6000-7f85942a7000 rw-p ... 7fff61284000-7fff6129a000 rw-p ... [stack] 7fff613fe000-7fff61400000 r-xp ... [vdso] ffffffffff600000-ffffffffff601000 r-xp ... [vsyscall] 8

  9. $ perl -e 'system(" cat /proc/$$/smaps ")' # note ‘smaps’ not ‘maps’ address perms ... pathname ... 7fb00fbc1000-7fb00fd22000 r-xp ... /.../5.10.1/x86_64-linux/CORE/libperl.so Size: 1412 kB <- size of executable code in libperl.so Rss: 720 kB <- amount that's in physical memory Pss: 364 kB Shared_Clean: 712 kB Shared_Dirty: 0 kB Private_Clean: 8 kB Private_Dirty: 0 kB Referenced: 720 kB Anonymous: 0 kB AnonHugePages: 0 kB Swap: 0 kB KernelPageSize: 4 kB MMUPageSize: 4 kB ... repeated detail for every mapped item ... Process view: everything exists in sequential contiguous physical memory. Simple. System view: chunks of physical memory are mapped into place and loaded on demand, then taken away again when the process isn't looking. 9

  10. C Program Code To the program everything appears to be in physical memory. to be in physical memory. Read-only Data In reality that’s rarely the case. In reality that’s rarely the case. Read-write Data Memory is divided into pages Memory is divided into pages Heap Page size is typically 4KB ← Page ‘resident’ in physical ← Page ‘resident’ in physical memory memory ← Page not resident Pages: Pages: • • are loaded when first used • may be ‘paged out’ when the system • may be ‘paged out’ when the system Shared Lib Code needs the physical memory needs the physical memory • may be shared with other processes • may be shared with other processes Shared Lib R/O Data • may be copy-on-write, where are • may be copy-on-write, where are shared page becomes private when Shared Lib R/W Data first written to first written to C Stack System 10

  11. Key Points Pages of a process can be paged out if the system wants the physical ✦ memory. So Resident Set Size (RSS) can shrink even while the overall process size grows. Re private/shared/copy-on-write: If a page is currently paged out its ✦ attributes are paged out as well. In this case a page is neither reported as private nor as shared. It is only included in the process size. So be careful to understand what you’re actually measuring! ✦ Generally total memory size is a good indicator. ✦ 11

  12. Low-Level Modules BSD::Resource - getrusage() system call (limited on Linux) ✦ BSD::Process - Only works on BSD, not Linux ✦ Proc::ProcessTable - Interesting but buggy ✦ Linux::Smaps - very detailed, but only works on Linux ✦ GTop - Perl interface to libgtop, better but external dependency ✦ 12

  13. Higher-Level Modules Memory::Usage ✦ Reads /proc/$pid/statm. Reports changes on demand. ✦ Dash::Leak ✦ Uses BSD::Process. Reports changes on demand. ✦ Devel::MemoryTrace::Light ✦ Uses GTop or BSD::Process. Automatically prints a message when ✦ memory use grows, pointing to a particular line number. Defaults to tracking Resident Set Size! ✦ 13

  14. Other Modules Devel::Plumber - memory leak finder for C programs ✦ Uses GDB to walk internal glibc heap structures. Can work on either a live ✦ process or a core file. Treats the C heap of the program under test as a collection of non-overlapping blocks, and classifies them into one of four states. Devel::Memalyzer - Base framework for analyzing program memory usage ✦ Runs and monitors a subprocess via plugins that read /proc smaps and status at ✦ regular intervals. Memchmark - Check memory consumption ✦ Memchmark forks a new process to run the sub and then monitors its memory ✦ usage every 100ms (approx.) recording the maximum amount used. 14

  15. A Peak at The Heap 15

  16. ← Your data goes here ← Your data goes here Heap Perl uses malloc() and Perl uses malloc() and free() to manage the space free() to manage the space malloc has its own issues malloc has its own issues (overheads, bucket sizes, (overheads, bucket sizes, fragmentation etc. etc.) fragmentation etc. etc.) Perl uses its own malloc Perl uses its own malloc code on some systems code on some systems On top of malloc perl has On top of malloc perl has it’s own layer of memory it’s own layer of memory management (e.g. arenas) management (e.g. arenas) for some data types for some data types 16

  17. Perl Data Memory 17

  18. Data Anatomy Examples Integer (IV) String (PV) Number with a string Head Body Data Illustrations from illguts 18

  19. Array (IV) Hash (HV) 19

  20. Glob (GV) Symbol Table (Stash) Sub Pad List lots of tiny chunks! 20

  21. Notes All Heads and Bodies are allocated from arenas managed by perl ✦ efficient, low overhead and no fragmentation ✦ but arena space for a given data type is never freed or repurposed ✦ All variable length data storage comes from malloc ✦ higher overheads, bucket and fragmentation issues ✦ Summing the “apparent size” of a data structure will underestimate ✦ the actual “space cost”. 21

  22. Arenas $ perl -MDevel::Gladiator=arena_table -e 'warn arena_table()' ARENA COUNTS: 1063 SCALAR 199 GLOB 120 ARRAY 95 CODE 66 HASH 8 REGEXP 5 REF 4 IO::File 3 REF-ARRAY 2 FORMAT 1 version 1 REF-HASH 1 REF-version arena_table() formats the hash return by arena_ref_counts() which summarizes the list of all SVs returned by walk_arenas() . 22

  23. Devel::Peek • Gives you a textual view of the data structures $ perl -MDevel::Peek -e ' %a = (42 => "Hello World!"); Dump(\%a) ' SV = IV(0x1332fd0) at 0x1332fe0 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x1346730 SV = PVHV(0x1339090) at 0x1346730 REFCNT = 2 FLAGS = (SHAREKEYS) ARRAY = 0x1378750 (0:7, 1:1) hash quality = 100.0% KEYS = 1 FILL = 1 MAX = 7 RITER = -1 EITER = 0x0 Elt "42" HASH = 0x73caace8 SV = PV(0x1331090) at 0x1332de8 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x133f960 "Hello World!"\0 CUR = 12 <= length in use LEN = 16 <= amount allocated 23

Recommend


More recommend