IBM Java Memory Management - trochu delsi

Zdenek Kaminski sutr na valasske-laboratore.cz
Pondělí Září 14 15:29:12 CEST 2009


Ahoj ,

v AIXu funguje alokace v pameti jak je popsano v nize uvedenem textu. Moje
otazka je, jestli (ci spise jakym zpusobem) je mozne se podobnym zpusobem 
podivat do procesu na 32bit linuxu?

A pokud by me nekdo vice nez nakopnul, bylo by to super.
Hezky zbytek dne.

Z.K.



Understanding memory usage
==========================

Before you can properly diagnose memory problems on AIX, first you must 
have an understanding of the AIX virtual memory model and how the JVM 
interacts with it.


32- and 64-bit JVMs
--------------------

Most of the information in this section about altering the memory model 
and running out of native heap is relevant only to the 32-bit model, 
because the 64-bit model does not suffer from the same kind of memory 
constraints.

The 64-bit JVM can suffer from memory leaks in the native heap, and the 
same methods can be used to identify and pinpoint those leaks. The 
information regarding the Java heap relates to both 32- and 64-bit JVMs.


The 32-bit AIX Virtual Memory Model
-----------------------------------

  AIX assigns a virtual address space partitioned into 16 segments of 256MB.

Processing address space to data is managed at the segment level, so a 
data segment can either be shared (between processes), or private.

Segment 0x0 is assigned to the kernel.
Segment 0x1 is application program text (static native code).
Segment 0x2 is the application program data and application stack
(primordial thread stack and private data).
Segments 0x3 to 0xC are shared memory available to all processes.
Segment 0xD is the shared library text.
Segment 0xE is also shared memory and miscellaneous kernel usage.
Segment 0xF is the data area.


Monitoring the native heap
--------------------------

You can monitor the memory usage of a process by taking a series of 
snapshots over regular time intervals of the memory currently allocated 
and committed. Use svmon like this:

svmon -P [pid] -m -r -i [interval] > output.filename

  Use the -r flag to print the address range. Because the Java heap is 
allocated using mmap() or shmat(), it is clear whether memory allocated to 
a specific segment of memory (under "Esid") is allocated to the Java or 
the native heap. The type and description fields for each of the segments 
allows the determination of which sections are native or Java heap.

Segments allocated using mmap or shmat are listed as "mmap mapped to" or 
"extended shm segments" and are the Java heap. Segments allocated using 
malloc will be marked as "working storage" and are in the native heap. 
This demarcation makes it possible to monitor the growth of the native 
heap separately from the Java heap (which should be monitored using 
verbose GC). Here is the svmon output from the command that is shown 
above:

-------------------------------------------------------------------------------
Pid Command Inuse Pin Pgsp Virtual 64-bit Mthrd LPage
29670 java 87347 4782 5181 95830 N Y N
Vsid Esid Type Description LPage Inuse Pin Pgsp Virtual
50e9 - work - 41382 0 0 41382
Addr Range: 0..41381
9dfb - work - 28170 0 2550 30720
Addr Range: 0..30719
ddf3 3 work working storage - 9165 0 979 10140
Addr Range: 0..16944
0 0 work kernel seg - 5118 4766 1322 6420
Addr Range: 0..11167
c819 d work text or shared-lib code seg - 2038 0 283 6813
Addr Range: 0..10219
2ded f work working storage - 191 0 20 224
Addr Range: 0..4150
f5f6 - work - 41 14 4 45
Addr Range: 0..49377
6e05 2 work process private - 35 2 23 58
Addr Range: 65296..65535
1140 6 work other segments - 26 0 0 26
Addr Range: 0..32780
cdf1 - work - 2 0 0 2
Addr Range: 0..5277
e93f - work - 0 0 0 0
3164 c mmap mapped to sid 1941 - 0 0 - -
2166 - work - 0 0 0 0
496b b mmap mapped to sid 2166 - 0 0 - -
b51e - clnt /dev/fslv00:44722 - 0 0 - -
Addr Range: 0..207
ee1c a mmap mapped to sid e93f - 0 0 - -
1941 - work - 0 0 0 0
1081 7 mmap mapped to sid 9dfb - 0 0 - -
edf5 8 mmap mapped to sid 50e9 - 0 0 - -
c01b 9 mmap mapped to sid cdf1 - 0 0 - -

The actual memory values for the mmap allocated segments are stored 
against a Vsid of type ?work?. For example, the memory usage in segment 7 
(Java heap):

1081 7 mmap mapped to sid 9dfb - 0 0 - -

is described against Vsid 9dfb, which reads as follows:
9dfb - work - 28170 0 2550 30720 Addr Range: 0..30719


Native heap usage
-----------------

The native heap usage will normally grow to a stable level, and then stay 
at around that level. You can monitor the amount of memory committed to 
the native heap by observing the number of ?Inuse? pages in the svmon 
output. However, note that as JIT compiled code is allocated to the native 
heap with malloc(), there might be a steady slow increase in native heap 
usage as little used methods reach the threshold to undergo JIT 
compilation. You can monitor the JIT compiling of code to avoid confusing 
this behavior with a memory leak. To do this, run with the command-line 
option

-Xjit:verbose={compileStart|compileEnd}.

  This command causes each method
name to print to stderr as it is being compiled and, as it finishes
compiling, the
location in memory where the compiled code is stored.

(warm) Compiling java/lang/System.getEncoding(I)Ljava/lang/String;
+ (warm) java/lang/System.getEncoding(I)Ljava/lang/String; @ 0x02BA0028-0x02BA0113
(2) Compiling java/lang/String.hashCode()I
+ (warm) java/lang/String.hashCode()I @ 0x02BA0150-0x02BA0229
(2) Compiling java/util/HashMap.put(Ljava/lang/Object;Ljava/lang/Object;) Ljava/lang/Object;
+ (warm) java/util/HashMap.put(Ljava/lang/Object;Ljava/lang/Object;) Ljava/lang/Object; @ 0x02BA0270-0x02BA03F7
(2) Compiling java/lang/String.charAt(I)C
+ (warm) java/lang/String.charAt(I)C @ 0x02BA0430-0x02BA04AC
(2) Compiling java/util/Locale.toLowerCase(Ljava/lang/String;) Ljava/lang/String;
+ (warm) java/util/Locale.toLowerCase(Ljava/lang/String;)Ljava/lang/String; @ 0x02BA04D0-0x02BA064C

When you have monitored how much native heap you are using, you can 
increase or decrease the maximum native heap available by altering the 
size of the Java heap. This relationship between the heaps occurs because 
the process address space not used by the Java heap is available for the 
native heap usage. You must increase the native heap if the process is 
generating errors relating to a failure to allocate native resources or 
exhaustion of process address space. These errors can take the form of a 
JVM internal error message or a detail message associated with an 
OutOfMemoryError. The message associated with the relevant errors will 
make it clear that the problem is native heap exhaustion.




Další informace o konferenci Linux