티스토리 뷰

이전 글에서는 프로세스의 RSS와 VSZ로 모니터링 되는 java 프로세스의 메모리가 어떤 의미인지를 살펴보았다. 이번에는 이 Pmap의 결과에서 Heap메모리가 어디에 할당되는지를 알아보도록 하겠다.

이것이 1052 프로세스의 Pmap의 결과이다. 이 결과는 할당 받은 메모리 block마다 한 row씩 표현이 되어 있다. 각 Memory Block은 네 부분의 정보로 구성이 되어 있다. 첫번째 정보는 메모리가 시작하는 주소이다. 이것은 16자리의 16bit Hexa로 표현되어 있다. 다시 말해 64bit( = 16^16= (2^4)^16))를 표현할 수 있다는 얘기가 되는데 이 머신은 32bit이기 때문에 상위 8자리는 아무 의미가 없고 하위 8자리만 의미가 있다.

두번째는 memory block의 크기로 KB단위로 표현되어 있다. 세번째는 권한이고 네번째는 Memory Block의 내용을 의미한다. 만약 메모리에 파일이나 디렉토리처럼 명확한 것이라면 그 이름을 표현하지만 Java의 Heap과 같이 메모리 속성이라면 OS는 굳이 이름을 붙이지 않고 Anonymous를 의미하는 ' [ anon ]' 이라고 표현한다.

 

[jeus5@InterMax2 ~]$ pmap 1052
1052: /usr/local/java_1.4/bin/java -server -Xmx512m -Xbootclasspath/p:/home/jeus5/jeus5/lib/system/extension.jar -classpath /home/jeus5/intermax/jspd-2.9.2/lib/aspectjweaver.jar:/home/jeus5/intermax/jspd-2.9.2/lib/ojdbc14.jar:/home/jeus5/jeus5/lib/system/bootstrap.jar -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.library.path=/home/jeus5/jeus5/lib/system -Djava.naming.factory.initial=jeus.jndi.JNSContextFactory -Djava.naming.factory.url.pkgs=jeus.jndi.jns.url -Djava.net.p
00000000002a4000 88K r-x-- /lib/ld-2.3.4.so
00000000002ba000 4K r-x-- /lib/ld-2.3.4.so
00000000002bb000 4K rwx-- /lib/ld-2.3.4.so
00000000002be000 1176K r-x-- /lib/tls/libc-2.3.4.so
00000000003e4000 8K r-x-- /lib/tls/libc-2.3.4.so
00000000003e6000 8K rwx-- /lib/tls/libc-2.3.4.so
00000000003e8000 8K rwx-- [ anon ]
00000000003ec000 132K r-x-- /lib/tls/libm-2.3.4.so
000000000040d000 4K r-x-- /lib/tls/libm-2.3.4.so

000000000040e000 4K rwx-- /lib/tls/libm-2.3.4.so
0000000000411000 8K r-x-- /lib/libdl-2.3.4.so
0000000000413000 4K r-x-- /lib/libdl-2.3.4.so
0000000000414000 4K rwx-- /lib/libdl-2.3.4.so
0000000000429000 56K r-x-- /lib/tls/libpthread-2.3.4.so
0000000000437000 4K r-x-- /lib/tls/libpthread-2.3.4.so
0000000000438000 4K rwx-- /lib/tls/libpthread-2.3.4.so
0000000000439000 8K rwx-- [ anon ]
000000000052b000 76K r-x-- /lib/libnsl-2.3.4.so
000000000053e000 4K r-x-- /lib/libnsl-2.3.4.so
000000000053f000 4K rwx-- /lib/libnsl-2.3.4.so
0000000000540000 8K rwx-- [ anon ]
===============================================================================================

===============================================================================================
0000000008048000 44K r-x-- /usr/local/j2sdk1.4.2_17/bin/java
0000000008053000 8K rwx-- /usr/local/j2sdk1.4.2_17/bin/java
0000000008055000 14564K rwx-- [ anon ]
===============================================================================================
00000000c63b4000 4K ----- [ anon ]

00000000c7aea000 12K ----- [ anon ]
00000000c7aed000 448K rwx-- [ anon ]
00000000c7b5d000 452K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/javassist.jar
00000000c7bce000 360K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/log4j-1.2.14.jar
00000000c7c28000 40K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/hivemind-jmx-1.1.1.jar
00000000c7c32000 68K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/commons-io-1.2.jar
00000000c7c43000 312K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/tapestry-contrib-4.0.2.jar
00000000c7c91000 40K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/tapestry-annotations-4.0.2.jar
00000000c7c9b000 140K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/jCharts-0.7.5.jar
00000000c7cbe000 76K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/hivemind-lib-1.1.1.jar
00000000c7cd1000 1064K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/tapestry-4.0.2.jar
00000000c7ddb000 32K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/commons-fileupload-1.1.1.jar
00000000c7de3000 52K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/commons-logging-1.1.jar
00000000c7df0000 48K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/commons-codec-1.3.jar
00000000c7dfc000 380K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/hivemind-1.1.1.jar
00000000c7e5b000 168K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/ognl-2.6.9.jar
00000000c7e85000 240K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/commons-lang-2.2.jar
00000000c7ec1000 64K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/jakarta-oro-2.0.8.jar
00000000c7ed1000 188K r-xs- /jeus5/webhome/admin_home/WEB-INF/lib/commons-beanutils.jar
00000000c7f00000 236K rwx-- [ anon ]
00000000c7f3b000 788K ----- [ anon ]
00000000c8013000 4K r-x-- /home/jeus5/jeus5/lib/system/libCUtility.so
00000000c8014000 4K rwx-- /home/jeus5/jeus5/lib/system/libCUtility.so

00000000ce71f000 48K rwx-- [ anon ]
00000000ce72b000 80K rwx-- [ anon ]

00000000ce73f000 5252K rwx-- [ anon ]
00000000cec60000 52992K rwx-- [ anon ]
00000000d2020000 41500K rwx-- [ anon ]
00000000d48a7000 424548K rwx-- [ anon ]

00000000ee740000 23040K rwx-- [ anon ]
00000000efdc0000 42496K rwx-- [ anon ]
-----------------------------------------------------------------------------------------------
00000000f274c000 216K rwx-- [ anon ]
00000000f2782000 712K rwx-- [ anon ]
00000000f2834000 3584K rwx-- [ anon ]
00000000f2bb4000 45568K rwx-- [ anon ]
00000000f5834000 5972K r-xs- /usr/local/j2sdk1.4.2_17/jre/lib/charsets.jar
00000000f5e09000 72K r-xs- /usr/local/j2sdk1.4.2_17/jre/lib/jce.jar
00000000f5e1b000 884K r-xs- /usr/local/j2sdk1.4.2_17/jre/lib/jsse.jar
00000000f5ef8000 88K r-xs- /usr/local/j2sdk1.4.2_17/jre/lib/sunrsasign.jar
00000000f5f0e000 296K rwx-- [ anon ]
00000000f5f58000 26364K r-xs- /usr/local/j2sdk1.4.2_17/jre/lib/rt.jar
00000000f7917000 56K r-xs- /home/jeus5/jeus5/lib/system/extension.jar
00000000f7925000 56K r-x-- /usr/local/j2sdk1.4.2_17/jre/lib/i386/libzip.so
00000000f7933000 8K rwx-- /usr/local/j2sdk1.4.2_17/jre/lib/i386/libzip.so
00000000f7935000 112K r-x-- /usr/local/j2sdk1.4.2_17/jre/lib/i386/libjava.so
00000000f7951000 8K rwx-- /usr/local/j2sdk1.4.2_17/jre/lib/i386/libjava.so
00000000f7953000 36K r-x-- /lib/libnss_files-2.3.4.so
00000000f795c000 4K r-x-- /lib/libnss_files-2.3.4.so
00000000f795d000 4K rwx-- /lib/libnss_files-2.3.4.so
00000000f7973000 52K r-x-- /usr/local/j2sdk1.4.2_17/jre/lib/i386/libverify.so
00000000f7980000 8K rwx-- /usr/local/j2sdk1.4.2_17/jre/lib/i386/libverify.so
00000000f7982000 16K rwxs- /tmp/hsperfdata_jeus5/1052
00000000f7986000 24K r-x-- /usr/local/j2sdk1.4.2_17/jre/lib/i386/native_threads/libhpi.so
00000000f798c000 8K rwx-- /usr/local/j2sdk1.4.2_17/jre/lib/i386/native_threads/libhpi.so
00000000f798e000 5976K r-x-- /usr/local/j2sdk1.4.2_17/jre/lib/i386/server/libjvm.so
00000000f7f64000 360K rwx-- /usr/local/j2sdk1.4.2_17/jre/lib/i386/server/libjvm.so
00000000f7fbe000 96K rwx-- [ anon ]
00000000ffe01000 40K rwx-- [ anon ]
00000000ffe0b000 12K ----- [ anon ]
00000000ffff0000 56K rwx-- [ stack ]
00000000ffffe000 4K r-x-- [ anon ]
total 828604K

 

그렇다면 여기서 우리가 설정한 -Xmx512m의 heap은 어디에 있을까? 이것을 찾기 전에 우선 Memory Layout에 대해 알아보는 것이 좋을 듯 하다. 가상 메모리를 지원하는 현대의 OS에서는 프로세스의 가상 메모리와 실제 물리 메모리와의 매핑을 통해 프로그램을 실행한다. 가상 메모리는 프로세스마다 Virtual Address Space(VAS)를 지원한다. 32bit의 경우 물리 메모리의 용량과는 관계없이 Process의 VAS는 4GB의 크기로 생성된다.

그리고 이 VAS의 Layout은 CPU와 OS에 따라 달라진다.위의 Pmap의 결과는 Intel Quad Core CPU를 사용하는 32bit Linux머신의 것이고 이 Intel 32bit linux의 Address Space Layout은 아래와 같다.


(출처 : http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory )

 

이 Layout이 의미하는 것은 VAS의 각 영역은 이미 특정한 Region 별로 할당이 되고 있다는 것이다. 다시 말해 어떤 프로그램이 실행 될 때 0x0804800부터 실행파일을 위해 주소를 할당하고 이를 위한 데이터와 shared library는 특정 region에 할당된다는 것이다.

Pmap의 결과에서도 이러한 규칙을 엿볼 수 있다. Memory의 특성에 맞게 그 군집을 표로 나타내면 아래와 같다. 메모리는 그 특성에 맞게 일정한 Memory의 Range내에서 모여 주소를 할당받고 있음을 알 수 있다.

Address Range 

Memory Region 

0x002a4000 ~ 0x00540000 

Shred Libraries 

0x08048000 ~ 0x00855000 

Executable Text (java) 

0xc63b4000 ~ 0xf2740000
(0xce73f000 ~ 0xee740000)

Java, jni libraries
(Java Heap)

0xf274c000 ~ 0xfffff000 

Jvm libraries

 

그런데 앞서 언급된 Linux의 Address space Layout과 비교해 보면 Executable Text를 제외하고는 일치하는 부분이 거의 없고 Java Heap을 포함한 대부분의 데이터가 Kernel space에 몰려 있음을 알 수 있다. 이것은 Layout이 틀리거나 Pmap의 결과가 잘못된 것이 아니라 OS가 보안을 위해 Address space Randomization 기법을 사용하기 때문이다. 이는 buffer overflow 같은(버퍼 경계를 넘어서는 데이터를 보전시켜 그 결과 넘치는 데이터를 메모리에 인접한 부분에 겹쳐 쓰게 하여 머신을 다운 시키거나 악질적인 코드가 실행되게끔 하는 해킹방법) 악의적인 해킹을 방지하기 위해 지정된 layout과 다른 주소로 할당 받는 방법을 말한다.

여기서 Java Heap에 대해 관심을 집중해 볼 필요가 있다. 우리는 이 java heap을 –Xmx512m 라는 옵션으로 만들었고 실제 메모리 사용은 100Mb정도이기 때문에 Max까지 할당되지는 않았을 것이다. 그럼에도 불구하고 현재 몇 개의 region으로 512Mb정도의 사이즈가 이미 할당이 되어 있음을 알 수 있다. 다시 말해 VAS에서의 메모리의 할당은 실제 사용여부와는 상관 없이 사용 가능한 만큼 할당을 하는 것으로 생각해 볼 수 있다.

그리고 참고로 java Heap이 여러 region으로 나뉘어 있는 것은 Hotspot JVM이 Generation구조를 가지고 있기 때문으로 생각된다. 실제로 Young generation과 Old Generation의 크기를 고정으로 맞추고 java를 기동 시키면 memory region도 그에 맞게 변하는 것을 알 수 있다.

아래는 memory option에 의해 heap의 memory range가 다르게 설정되는 것을 나타내는 것이다. 그렇지만 규칙적으로 0xcf98f000~0xefd90000 사이의 범위의 516Mb만큼은 고수를 하고 있는 것으로 보아 가상 메모리에서 Heap은 사용할 수 있는 만큼의 범위를 할당하여 사용함은 분명한 듯 하다.

[jeus5@InterMax2 ~]$ pmap 7113
7113: java -Xms512m -Xmx512m -Xmn256m -XX:SurvivorRatio=8 -Dname=TEST Test
00000000cf98f000 528388K rwx-- [ anon ]
00000000efd90000 61440K rwx-- [ anon ]
total 674848K

[jeus5@InterMax2 ~]$ pmap 7127
7127: java -Xmx512m -Xmn256m -XX:SurvivorRatio=8 -Dname=TEST Test
00000000cf98f000 263556K rwx-- [ anon ]
00000000dfaf0000 260736K rwx-- [ anon ]

00000000efd90000 61440K rwx-- [ anon ]
total 674848K

[jeus5@InterMax2 ~]$ pmap 7142
7142: java -Xmx512m -Dname=TEST Test
00000000cf98f000 644K rwx-- [ anon ]
00000000cfa30000 39680K rwx-- [ anon ]
00000000d20f0000 1408K rwx-- [ anon ]
00000000d2250000 482560K rwx-- [ anon ]
00000000ef990000 4096K rwx-- [ anon ]
00000000efd90000 61440K rwx-- [ anon ]

댓글
댓글쓰기 폼