HOWTO: Fine tune application memory consumption (Excelsior JET 3.7 and below)
Article ID: 000002 PDF Version: 000002.pdf The information in this article applies to:
This article does not apply to Excelsior JET 4.0 and above. The similar article for Excelsior JET 4.0 and above can be found here 000025. It’s quite complicated if at all possible to configure a Java memory manager following the “one size fits all” principle. Applications consume memory in different ways and have different requirements to performance and memory footprint. The behavior of the memory manager and the garbage collector in particular is therefore application-specific.
The first sample cited in this article illustrates behavior of a model application with respect to memory consumption. We examine that behavior and show how to change it by adjusting the “heaplimit” and “ratio” parameters of the JET runtime system. The more complicated second sample help us to assess the effect of heap defragmentation on memory consumption and performance. Source files and build/run scripts for this article may be found here. Excelsior JET memory manager has the following configuration parameters:
Default settings:
Consider a simple program that constantly creates new heap objects:
An instance of the MemUse class contains only one field roots, which is an array of type String. In the method createBlocks(), new objects are allocated and assigned to the array’s elements in an infinite loop. Thus, at any time during sample run there are at most 100 alive objects in the heap. Other objects allocated by the sample are considered garbage and should be reclaimed by the GC when it starts. Simplicity of this sample does not prevent revealing the changes in the JET memory manager behavior when values of parameters are changed.
For different combinations of the parameters, we monitored memory consumption via the "Mem Usage" column of Windows Task Manager (that includes all memory used by the process, not just the heap). The following table contains some sample results: Table: Maximum memory usage, MB
As you can see, if ratio is high enough, the garbage collector is invoked so frequently that heaplimit is never reached. The default value of 1.1% is definitely too low for this particular application. 5% may be enough, whereas 20% would keep memory usage to a minimum.
Setting heaplimit value to 0 switches the memory manager to the “adaptive” mode. In this mode, the JET runtime uses not more than 75% of available physical memory. If there’s not enough physical memory, OutOfMemoryError will be thrown. So if you want your application to make use of virtual memory, you should specify an explicit value of the heaplimit parameter. In this case, however, memory paging would occur if there is no available physical memory left, increasing GC pauses by orders of magnitude. Note: Since the behavior of the memory manager and the garbage collector in particular is application-specific, increasing ratio does not necessarily result in lower memory consumption, and decreasing it does not always improve application performance. You have to experiment with your particular application to find the optimum ratio for it. By changing the heaplimit value, you may either improve application performance or deteriorate it. In general, it is recommended to use adaptive heaplimit when you know that your application will work “alone” or that the target systems will have enough physical memory. You have to experiment with your particular application to find the best values for heaplimit and ratio with respect to performance and memory consumption. Consider the DemoSort sample program, which sorts an array of objects using four different sort algorithms. We intentionally “unoptimized” those algorithms by changing the method swap() as follows:
The tables below demonstrate the impact of memory manager settings on performance and memory consumption of this sample: auto defragmentation
forced defragmentation
As can be seen, forcing defragmentation significantly reduces memory consumption but also deteriorates performance.
In most cases, forcing defragmentation will increase GC pauses and thus slow down your application. However, under certain circumstances, e.g. on systems with low RAM capacity, it may actually improve overall performance. Also, the changes in memory consumption and performance are application-specific, so it is up to you to experiment and then decide whether frequent heap defragmentation is benefical to your application. Copyright © 2003-2006 Excelsior LLC. All rights reserved.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Home | Company | Products | Services | Resources | Blog | Contact | Request a Call Site: Search | Forum | Credits © 1999-2006 Excelsior LLC. All Rights Reserved. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||