+ All Categories
Home > Technology > Perl Memory Use - LPW2013

Perl Memory Use - LPW2013

Date post: 10-May-2015
Category:
Upload: tim-bunce
View: 2,207 times
Download: 4 times
Share this document with a friend
Description:
Slides for my talk at the London Perl Workshop in Nov 2013, featuring the Devel::SizeMe perl module. See also the screencast at https://archive.org/details/Perl-Memory-Profiling-LPW2013
Popular Tags:
37
Perl Memory Use Tim Bunce @ London Perl Workshop 2013
Transcript
Page 1: Perl Memory Use - LPW2013

Perl Memory UseTim Bunce @ London Perl Workshop 2013

Page 2: Perl Memory Use - LPW2013

Ouch!

$ perl some_script.plOut of memory!$

$ perl some_script.plKilled.$

$ perl some_script.pl$Someone shouts: "Hey! My process has been killed!"

$ perl some_script.pl[...later...] "Why is it taking so long?"

Page 3: Perl Memory Use - LPW2013

Process Memory

Page 4: Perl Memory Use - LPW2013

$ perl -e 'system("cat /proc/$$/stat")' # $$ = pid4752 (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 SZ120236 1764 30059 640

$ perl -e 'system("top -b -n1 -p $$")'... PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND13063 tim 20 0 117m 1764 1384 S 0.0 0.1 0:00.00 perl

$ perl -e 'system("cat /proc/$$/status")'...VmPeak:! 120236 kBVmSize:! 120236 kB <- total (code, libs, stack, heap etc.)VmHWM:! 1760 kBVmRSS:! 1760 kB <- how much of the total is resident in physical memoryVmData:! 548 kB <- data (heap)VmStk:! 92 kB <- stackVmExe:! 4 kB <- codeVmLib:! 4220 kB <- libs, including libperl.soVmPTE:! 84 kBVmPTD:! 28 kBVmSwap:! 0 kB ... Further info on unix.stackexchange.com

Page 5: Perl Memory Use - LPW2013

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 libShared Lib R/W Data //

C Stack (not the perl stack)System

Page 6: Perl Memory Use - LPW2013

$ perl -e 'system("cat /proc/$$/maps")'address perms ... pathname00400000-00401000 r-xp ... /.../perl-5.NN.N/bin/perl00601000-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.so7f8592e1a000-7f859301a000 ---p ... /lib64/libc-2.12.so7f859301a000-7f859301e000 r--p ... /lib64/libc-2.12.so7f859301e000-7f859301f000 rw-p ... /lib64/libc-2.12.so7f859301f000-7f8593024000 rw-p ...

...other libs...

7f8593d1b000-7f8593e7c000 r-xp ... /.../lib/5.NN.N/x86_64-linux/CORE/libperl.so7f8593e7c000-7f859407c000 ---p ... /.../lib/5.NN.N/x86_64-linux/CORE/libperl.so7f859407c000-7f8594085000 rw-p ... /.../lib/5.NN.N/x86_64-linux/CORE/libperl.so7f85942a6000-7f85942a7000 rw-p ...

7fff61284000-7fff6129a000 rw-p ... [stack]

7fff613fe000-7fff61400000 r-xp ... [vdso]ffffffffff600000-ffffffffff601000 r-xp ... [vsyscall]

Page 7: Perl Memory Use - LPW2013

$ 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.soSize: 1412 kB <- size of executable code in libperl.soRss: 720 kB <- amount that's currently in physical memoryPss: 364 kBShared_Clean: 712 kBShared_Dirty: 0 kBPrivate_Clean: 8 kBPrivate_Dirty: 0 kBReferenced: 720 kBAnonymous: 0 kBAnonHugePages: 0 kBSwap: 0 kBKernelPageSize: 4 kBMMUPageSize: 4 kB

... repeated for every segment ...

... repeated for every segment ...

Page 8: Perl Memory Use - LPW2013

Memory Pages

✦ Process view:

✦ Large continuous regions of memory. Simple.

✦ Operating System view:

✦ Memory is divided into pages

✦ Pages are loaded to physical memory on demand

✦ Mapping can change without the process knowing

Page 9: Perl Memory Use - LPW2013

C Program Code

Memory is divided into pagesPage size is typically 4KB

Read-only Data Memory is divided into pagesPage size is typically 4KBRead-write Data

Memory is divided into pagesPage size is typically 4KB

Heap

Memory is divided into pagesPage size is typically 4KB

← Page ‘resident’ in physical memory ← Page not resident

← Page ‘resident’ in physical memory ← Page not resident

← Page ‘resident’ in physical memory ← Page not resident

RSS “Resident Set Size”is how much process memory is currently in physical memory

RSS “Resident Set Size”is how much process memory is currently in physical memoryShared Lib Code

RSS “Resident Set Size”is how much process memory is currently in physical memory

Shared Lib R/O Data

RSS “Resident Set Size”is how much process memory is currently in physical memory

Shared Lib R/W Data

RSS “Resident Set Size”is how much process memory is currently in physical memory

RSS “Resident Set Size”is how much process memory is currently in physical memory

RSS “Resident Set Size”is how much process memory is currently in physical memory

C Stack

RSS “Resident Set Size”is how much process memory is currently in physical memory

System

RSS “Resident Set Size”is how much process memory is currently in physical memory

Page 10: Perl Memory Use - LPW2013

Key Point

✦ Don’t use Resident Set Size (RSS)

✦ Unless you really want to know what’s currently resident.

✦ It can shrink even while the process size grows.

✦ Heap size or Total memory size is a good indicator.

Page 11: Perl Memory Use - LPW2013

Malloc andThe Heap

Page 12: Perl Memory Use - LPW2013

“Malloc andThe Heap”

Page 13: Perl Memory Use - LPW2013

Heap ← Your perl stuff goes here

Page 14: Perl Memory Use - LPW2013

Heap

malloc() requests big chunks of memory from the

operating system as needed.Almost never returns it!

Perl makes lots of malloc and free requests.

Freed fragments of various sizes accumulate.

malloc() requests big chunks of memory from the

operating system as needed.Almost never returns it!

Perl makes lots of malloc and free requests.

Freed fragments of various sizes accumulate.

malloc() requests big chunks of memory from the

operating system as needed.Almost never returns it!

Perl makes lots of malloc and free requests.

Freed fragments of various sizes accumulate.

malloc() requests big chunks of memory from the

operating system as needed.Almost never returns it!

Perl makes lots of malloc and free requests.

Freed fragments of various sizes accumulate.

malloc() requests big chunks of memory from the

operating system as needed.Almost never returns it!

Perl makes lots of malloc and free requests.

Freed fragments of various sizes accumulate.

malloc() requests big chunks of memory from the

operating system as needed.Almost never returns it!

Perl makes lots of malloc and free requests.

Freed fragments of various sizes accumulate.

malloc() requests big chunks of memory from the

operating system as needed.Almost never returns it!

Perl makes lots of malloc and free requests.

Freed fragments of various sizes accumulate.

malloc() requests big chunks of memory from the

operating system as needed.Almost never returns it!

Perl makes lots of malloc and free requests.

Freed fragments of various sizes accumulate.

perl data

malloc manages memory allocation

Page 15: Perl Memory Use - LPW2013

Your Data

Page 16: Perl Memory Use - LPW2013

Perl Data Anatomy

Head Body Data

Integer (IV)

String (PV)

Number with a string

Illustrations from illguts

Page 17: Perl Memory Use - LPW2013

Array (IV)

Hash (HV)

Page 18: Perl Memory Use - LPW2013

Glob (GV) Symbol Table (Stash)

Sub (CV)

lots of tiny chunks!

Page 19: Perl Memory Use - LPW2013

Devel::Peek• Gives you a textual view of data

$ 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) KEYS = 1 FILL = 1 MAX = 7 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

Page 20: Perl Memory Use - LPW2013

Devel::Size• Gives you a measure of the size of a data structure

$ perl -MDevel::Size=total_size -le 'print total_size( 0 )'24

$ perl -MDevel::Size=total_size -le 'print total_size( [] )'64

$ perl -MDevel::Size=total_size -le 'print total_size( {} )'120

$ perl -MDevel::Size=total_size -le 'print total_size( [ 1..100 ] )'3264

• Created by Dan Sugalski, now maintained by Nicholas Clark• Is very fast, and accurate for most simple data types.• Has limitations and bugs, but is the best tool we have.

Page 21: Perl Memory Use - LPW2013

ArenasHeads and Bodies are allocated from ‘arenas’ (slabs) managed by perl.

One for SV heads an one for each size of SV body.

More efficient than malloc in space and speed.

Introspect arenas with Devel::Arena and Devel::Gladiator.

$ perl -MDevel::Gladiator=arena_table -e 'warn arena_table()' ARENA COUNTS: 1063 SCALAR 199 GLOB 120 ARRAY 95 CODE 66 HASH ...

Page 22: Perl Memory Use - LPW2013

Key Notes

✦ All variable length data storage comes from malloc

✦ malloc has overheads, bucket and fragmentation issues

✦ Heads and Bodies are allocated from ‘arenas’ managed by perl

✦ Arenas have less overhead but are never freed

✦ Memory usage will always be higher than the sum of the sizes.

Page 23: Perl Memory Use - LPW2013

Memory Profiling

Page 24: Perl Memory Use - LPW2013

Memory Profiling?

✦ Track memory size over time?

✦ See where memory is allocated and freed?

✦ Experiments with Devel::NYTProf

✦ Turned out to not be very useful

✦ Need to know what is ‘holding’ memory.

Page 25: Perl Memory Use - LPW2013

Space in Hiding✦ Perl tends to consume extra memory to save time

✦ This can lead to surprises, for example:

✦ sub foo { my $var = "X" x 10_000_000;}foo(); # ~20MB still used after return!

✦ sub bar{ my $var = "X" x 10_000_000; bar($_[0]-1) if $_[0]; # recurse}bar(50); # ~1GB still used after return!

Page 26: Perl Memory Use - LPW2013

X-Ray Vision!

✦ Want to see inside the black box

✦ Want to know “where memory is being held”

✦ A snapshot “crawl and dump” approach

✦ Separate capture from analysis

Page 27: Perl Memory Use - LPW2013

My Plan (circa 2012)

✦ Extend Devel::Size✦ Add a C-level callback hook✦ Add some kind of "data path name" mechanism✦ Add a function to return the size of everything✦ Stream the data to disk✦ Write tools to manipilate, summarize & query the data✦ Write tools to visualize the data✦ Write tools to compare sets of data

Page 28: Perl Memory Use - LPW2013

Devel::SizeMe

✦ Fork of Devel::Size✦ Still very experimental✦ Lots of hacks and rough edges✦ Some deep refactoring needed✦ Still exploring what’s possible✦ ... but it seems useful now

Page 29: Perl Memory Use - LPW2013

Devel::SizeMe Outputs

✦ Text - handy for testing and simple structures✦ Graphviz - useful visualization for up to ~1000 nodes✦ Treemap - useful for simple top-down view (“blame”)✦ Gephi - full network view (structure, relationships)✦ SQLite db

✦ Very little analysis implemented yet✦ Ref-loops are isolated from “owners”

Page 30: Perl Memory Use - LPW2013

Devel::SizeMe Text

sizeme_store Text

SQLite db

sizeme_graph

Graphviz (dot)GEXF

Treemap in browser

??? Gephi

Page 31: Perl Memory Use - LPW2013

Demonstration

Page 32: Perl Memory Use - LPW2013

See https://archive.org/details/Perl-Memory-Profiling-LPW2013

Page 33: Perl Memory Use - LPW2013

Devel::SizeMe Summary✦ Focussed on memory use✦ Walks trees of pointers in perl internals✦ Can dump individual data structures✦ Stream-based - scales to any size of application✦ Multiple output formats✦ Very minimal and informal data model

Page 34: Perl Memory Use - LPW2013

Current Limitations

✦ Very minimal and informal data model✦ Ref loops gets separated out✦ Accumulating sizes up tree happens too soon✦ Can’t edit the tree without invalidating sizes✦ Needs a multi-phase processing pipeline✦ Needs a more task-oriented user interface

Page 35: Perl Memory Use - LPW2013

Recommendations

✦ Store the data in some kind of database✦ Perform transformations on the database data✦ Generate UI from the database - scalability✦ Express queries as db queries - flexibility✦ What kind of database? Relational or Graph?

Page 36: Perl Memory Use - LPW2013

Possible Futures

✦ Feed Devel::MAT data into SQLite✦ Feed SQLite data into Neo4j✦ Develop useful Cypher query fragments✦ Develop graph simplifications as plugins✦ Develop visualizations

Page 37: Perl Memory Use - LPW2013

Questions?

[email protected]://blog.timbunce.org

@timbunce


Recommended