Thursday Dec 14, 2006

Java HotSpot: load the VM from a non-primordial thread and effects on stack and heap limits

Part I: Launching the HotSpot VM from a non-primordial thread.


A primordial thread is the first thread created by the Operating System kernel when a process is created.

In the prior versions to Java SE 6, a user application has little or no control of the primordial thread attributes, once the thread is created the attributes cannot be modified. Launching HotSpot in the primordial thread poses several issues, see BugId: 6316197.

HotSpot requires the threads be correctly setup for stack size which may be user specified on the command line, the stackaddr the address at which the stack starts and the stack guard size. On Unix the stack size can be set using the shell (limit or ulimit), on Windows the PE header of the executable needs to be modified using special tools.

To circumvent these issues, the java launcher and the javaw launcher on Windows in JavaSE 6 will launch the HotSpot VM from a non-primordial thread. The following stack trace on Solaris shows the thread, notice that the primordial thread is waiting to rejoin, this happens when the process exits, the HotSpot VM is created and started in the ContinueInNewThread method.

6459:   /usr/java/bin/java Sleepy
----------------- lwp# 1 / thread# 1 --------------------
ff2c0fbc lwp_wait (2, ffbfe8cc)
ff2bc9bc _thrp_join (2, 0, ffbfe990, 1, ffbfe8cc, ff2ecbc0) + 34
ff2bcb28 thr_join (2, 0, ffbfe990, ffbfea20, 0, 0) + 10
00018a04 ContinueInNewThread (124c0, 0, 80000, ffbfea20, fffe7ccc, 0) + 30
00012480 main (18000, 2ac40, 10000, 2b1c8, 44c, 10001) + eb0
000111a0 _start (0, 0, 0, 0, 0, 0) + 108

 

 

 

 

 

 

JNI Applications which utilize custom launchers may use the same strategy illustrated by this simple example:
 

#include <stdio.h>
#include <jni.h>
#include <sys/types.h>
#include <unistd.h>

#include <pthread.h>

JavaVM\* jvm;

JNIEnv\* create_vm() {
JNIEnv\* env;
JavaVMInitArgs args;
JavaVMOption options[1];

args.version = JNI_VERSION_1_4;
args.nOptions = 1;
options[0].optionString = "-Djava.class.path=.";
args.options = options;
args.ignoreUnrecognized = JNI_FALSE;

JNI_CreateJavaVM(&jvm, (void \*\*)&env, &args);
return env;
}

void invoke_class(JNIEnv\* env) {
jclass helloWorldClass;
jmethodID mainMethod;
jobjectArray applicationArgs;
jstring applicationArg0;
char buf[128];

sprintf(buf, "%d", getpid());

helloWorldClass = (\*env)->FindClass(env, "HelloWorld");

mainMethod = (\*env)->GetStaticMethodID(env, helloWorldClass, "main", "([Ljava/lang/String;)V");

applicationArgs = (\*env)->NewObjectArray(env, 1, (\*env)->FindClass(env, "java/lang/String"), NULL);
applicationArg0 = (\*env)->NewStringUTF(env, buf);

(\*env)->SetObjectArrayElement(env, applicationArgs, 0, applicationArg0);
(\*env)->CallStaticVoidMethod(env, helloWorldClass, mainMethod, applicationArgs);
}

// VM Worker Thread
void\* dowork(void\* args) {
JNIEnv\* env = create_vm();
invoke_class( env );
// Unload the VM
if (jvm == NULL) exit(-1);

int retval = (\*jvm)->DetachCurrentThread(jvm);
if (retval != 0) exit(2);

retval = (\*jvm)->DestroyJavaVM(jvm);
if (retval != 0) exit(3);
}

int main(int argc, char \*\*argv) {
pthread_t tid;
void\* status;

// Create a new thread and launch the vm in that thread
pthread_create(&tid, NULL, dowork, NULL);

// Make the primordial wait until the VM worker thread exits
pthread_join(tid, &status);
exit(0);
}


Ta Dah, easier done than said!.

 Part II. The Java HotSpot Stack and Heap sizes

Several customers have asked me what sizes can be set for the heap and stack on the command line ?

This got me intrigued!,  upon some digging I found that there are lot of factors which limit these settings. The Operating System, Memory, Ergonomics and various other factors. So I wrote a little Java Program which basically interpolates the minimum and maximum values (gave me an excuse to use "KoolBeans" aka Netbeans, to quote a friend RK,  and a  committed Netbeans enthusiast).

The Java launcher supports Xms, Xmx and Xss, briefly, Xms sets the minimum heap size, Xmx sets the maximum heap size, and Xss sets the stack size, please see the man pages for further details. Typically the values for these options are chosen at run time by what is called as Ergonomics. Ergonomics is a feature built into the Java launcher, since Java SE 5. Based on the available physical memory and/or virtual memory, the number of processors, it sets the above values and also chooses  subsystems, such as the Garbage Collector and the JIT compilers.

In most cases the values for Xms, Xms, Xss have been carefully chosen for typical applications, for the optimum out of the box experience. There may be occasions to override these values for specific application needs. In such cases the acceptable values need to be known, on a given platform.  For those applications which could be redeployed, care must be taken to ensure the values chosen for one systems also works on all the desired target systems. Here is a Table empirical values of the limits based on my experiments, in some cases the mileage may vary. Why ?

Well, it must  be noted that certain values such as Xss maximum is severely restricted by the Operating System, the limits set by the shell and the actual available physical and virtual memory on the system. For Xmx, despite the availability  physical/virtual memory, the VM may not be able to fully utilize all of your free memory, due to fragmentation arising from loaded shared objects or dlls in the process address space. For instance on Windows, -Xmx1.6M perhaps will not work with Java Plugin, because of the overhead relating to the Web Browser and the dll's it loads  in the process address space.

Platform

Xms(min)

Xmx(max)

Xss(min)

solaris-sparc

2177K

3940K

96K

solaris-sparcv9

2817K

Limited by Virtual Memory

128K

solaris-i586

1025K

3108K

64K

solaris-amd64

2625K

Limited by Virtual Memory

64K

windows-i586

961K

1638K

1000

windows-amd64

2625K

Limited by Virtual Memory

1000

linux-i586

1025K

1936K

48K

linux-amd64

2625K

Limited by Virtual Memory

64K


So if you need a very large heap one should seriously consider using 64 bit platforms.

About

ksrini

Search

Categories
Archives
« December 2006 »
SunMonTueWedThuFriSat
     
1
2
3
4
5
6
7
8
9
10
11
12
13
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
      
Today