天天看點

Memory space manipulating in Java(Section three:Basic Knowledge of Java Process Heap )

Manipulate your Java process heap – Basic Knowledge

As I have mentioned at the beginning of Process Memory Model on AIX section, Java application in running itself is normally a process which most likely written in C/C++. When thinking about memory allocation of Java applications, nothing special from view of process level. Here I mean it is the same to other processes, you can use svmon to monitor how has it requested & allocated its memory space, use ps to view process specified information, use tprof to provide a detailed profile of CPU usage for it, and so on.

Now it is time for us to bring the internal action of JVM to light. In a running Java application, as I have mentioned above there should be a process heap for it. In fact, the Process Heap can be divided into two parts, which used for different purpose in JVM’s specification.

1)      Java Heap: This should be known to all Java developer, as it is the most common sense when we talk about Garbage Collection, OutOfMemory problem, heap in Java application, etc. This memory area, contains the instances of Java objects, and is often referred to simply as “the heap”.

2)      Native Heap: This one maybe seldom comes to our knowledge as its work is really being hidden behind the JVM. But you should know, it is the Native Heap, which is necessary to almost all of the processes running on AIX, and as to JVM process, it contains several critical components we can see in the following part.

Next, I am trying to give an explanation on differences between the two kinds of memory area:

1)      Maintenance Mechanism:

l        Java Heap is maintained by Garbage Collection (GC), and its size can be controlled via the -Xms and -Xmx setting when you start your Java application, you can monitor usage of your Java Heap by outputting activities of GC to a standard file like native_stderr.log (it is also known as verbosegc traces) in WebSphere environment.

l        While for Native Heap, the mechanism is usually depending on the platform. You can neither directly specify a size for it nor you can monitor its activities with any mechanism provided in Java. The memory space available to the native heap is that which isn't used by the Java heap, and by using svmon command on AIX, you can monitor the memory usage (allocated & committed) of a JVM process.

2)      Usage:

l        Java Heap is an entity entirely managed by JVM, as JVM interpret you Java program, any pure Java objects you declared in your program will be allocated with a memory space which is taking out of Java Heap by JVM. Just think it as a buffer pool managed by JVM, use for keeping your objects within their lifecycle. If you want to know more detail on how it is being used by Garbage Collection, refer to <a href >Resources</a> for links to more information on this topic.

l        Native Heap, which is platform-specific, would be a little different from one to another. On AIX it contains the following content of a JVM process:

Thread stacks for every thread except primordial

Buffers, lookup tables, and so on for ZIP-related operations (such as GZIPOutputStream methods)

Buffers and structures related to native GUIs underlying Swing/AWT (for example, Motif)

Data used by JNI code, such as native database drivers, MQ-Series, and so on

Just-in-time (JIT) compiler and Mixed-Mode-Interpreter (MMI) support routines

Executable code for JIT-compiled methods

including buffers used by JIT, data structures used by garbage collector, and any dynamic allocation using non-Java middleware invoked by the JVM. If your Java application uses JNI to invoke native code, the dynamic memory allocations done in the native code will also be coming out of the native heap.

3)      Allocation mechanism:

l        Java Heap, allocation mechanism taken in the various AIX Java releases have been changing. Basically, the approach for allocating this memory area can be either by using malloc() or mmap(), it will dependent on version of your Java release. Pay attention to that Java Heap has to be contiguous, so no matter what approach is being used you should prepared a large enough contiguous space for it.

l        Native Heap, as for this, malloc() will always be used for allocating, and Native Heap, it doesn’t require the memory space to be contiguous.

4)      I remember there should be still something different……

  The following table will give you a glance on how your Java Application is getting affected due to different mechanism adopted in different version of JDK.

JDK Version 1.1.8 1.2.2 1.3.1 1.4.0
default maxdata value 0x00000000 0x50000000 0x80000000 0x80000000
Java heap implementation mmap( ) mmap( )

Xmx<1GB :malloc( )

Otherwise: mmap( ) 1

Xmx<1GB : malloc( ), Otherwise: mmap( ) 1
-Xms default 1 MB 1 MB 1 MB 4 MB
-Xmx default 32 MB 64 MB 64 MB 64 MB
-Xmx maximum2 2 GB - 1 1280 MB 1 GB 1GB
Max. Java heap possible 8 segments ( 2 GB - 1 ) 8 segments ( 2 GB - 1) 10 segments( 2.5 GB ) 10 segments( 2.5 GB )
Max. native heap possible 3 Firstly you should count the max size your running Java Process can get (here we call it Process Heap). It is dependent on the memory model you specified. Then you can simple calculate Maximum of Native Heap by subtracting max Java Heap from Process Heap.

1 Starting from JDK 1.3.1, Java heap is allocated by using "malloc( )", when Java heap requested is less than 1GB, otherwise "mamp( )" will be used for the purpose. However, you can force Java to mmap its heap, regardless of heap size, by exporting the environment variable IBM_JAVA_MMAP_JAVA_HEAP=true.

2 Without patching the maxdata value in the Java command, the maximum value you can specify with -Xms and -Xmx is what's possible based on the combination of the maxdata and how Java heap is implemented.

  As to JDK1.4.1, because it supports the very large address-space memory model, we will discuss it separately here.

1.        With JDK 1.4.1, you do not have to be bothered with the setting of the LDR_CNTRL=MAXDATA environment variable any more. The 1.4.1 JVM now sets an appropriate maxdata value based on the maximum Java heap size requested by users using the -Xmx option specified in java commands. If LDR_CNTRL=MAXDATA is set before you start the JVM, the JVM uses the specified value; otherwise, the JVM uses the following algorithm to set LDR_CNTRL=MAXDATA:

      On AIX 5.2 or later

l         If the heap size is 3 GB or greater, [email protected] is set.

l         If the heap size is between 2.3 GB and 3 GB,

[email protected] is set.

l         If the heap size is less than 2.3 GB,

[email protected] is set.

2.        JDK 1.4.1 is just the same as JDK1.4.0 if you don’t use it for the very large address-space memory model. Below is a quick summary of how big Java heap and native heap are for Java process running with the three types of very large address-space models:

l         When maxdata is 0x00000000/dsa,

The native heap is in segment 2, sharing the 256 MB with thread stacks, all of JVM's non-object memory allocations, and privately loaded shared library code and data.

Your Java application can require a Java Heap range from 1GB to 3.25GB, while you should pay attention to your native heap, as only segment 2 can be used to allocate by using malloc(), which would cause a OutOfMemory error else.

l         When maxdata is no less than 0xB0000000/dsa,

The native heap is starting from segment 3.

Segments 4 through 15 are available for dynamic allocation to Java heap and native heap. You can request Java heap size up to 12 segments (3 GB). If you don't ask for all 12 segments for Java heap, the rest will be available for other shared memory needs and native heap.

Memory space allocated using shmat/mmap are allocated to start at segment 15 and grow toward lower numbered segments, while those allocated by using malloc () will start from segment 3 and grow toward higher.

l         When maxdata is less than 0xA0000000/dsa,

The native heap is starting from segment 3.

Maximum, segments 4 through 12 are available for dynamic allocation to Java heap and native heap(segment 14 is excluded because Java heap has to be contiguous). You can specify Java heap up to 9 segments (2.25 GB) with a presupposition that one segment is sufficient for your Native Heap.

With the basic knowledge of Java’s memory space I have outlined above, it becomes simpler for you to solve problems like JVM Crash, OutOfMemory and etc. But by using word becomes simpler here, I don’t mean to say that the work is simple. As to solve such a problem, besides the knowledge you should still know usage of several AIX commands, how to analysis you GC verbose, knowledge on how JNI is functioning and what you can set to your JIT Complier would be helpful.

In the next section, I will try to make a summary of problems which may happen due to memory allocation failed for process of your Java Application.