Server-class machine not detected as such

I have a RedHat Linux box with twin Xeon processors and 4Gb RAM. However, when running Java5 with default command-line arguments, it fails to detect that this machine is "server-class" and instead defaults to the HotSpot Client and a max heap of 64Mb.

(I've read http://java.sun.com/j2se/1.5.0/docs/guide/vm/server-class.html and am confident that the Linux box meets the requirements. See below for evidence).

Does anyone know exactly how the java process detects the CPUs, OS and installed RAM?

Obviously the workaround is to always specify the "-server" switch to run in a known configuration. But I'd be interested in knowing what is going on with the detection.

Here are some details:

$ uname -a

Linux xxxxxxxx 2.6.12.4-i386.HugeMem.NFS-VP #1 SMP Thu Sep 8 17:23:14 PDT 2005 i686 i686 i386 GNU/Linux

$ free -m

totalusedfreesharedbufferscached

Mem: 40583880177 04592683

-/+ buffers/cache:7373320

Swap: 8189 08188

$ cat /proc/cpuinfo

processor: 0

vendor_id: GenuineIntel

cpu family: 15

model: 2

model name: Intel(R) Xeon(TM) CPU 2.80GHz

stepping: 9

cpu MHz : 2799.943

cache size: 512 KB

<snip>

processor: 1

vendor_id: GenuineIntel

cpu family: 15

model: 2

model name: Intel(R) Xeon(TM) CPU 2.80GHz

stepping: 9

cpu MHz : 2799.943

cache size: 512 KB

<snip>

I wrote a quick test program:

publicclass TestMem{

privatestaticfinalint ONE_MB = (1024 * 1024);

publicstaticvoid main(String[] args){

System.out.println("Version: " + System.getProperties().getProperty("java.vm.version"));

System.out.println("VM: " + System.getProperties().getProperty("java.vm.name"));

final Runtime runtime = Runtime.getRuntime();

System.out.println("Available processors: " + runtime.availableProcessors());

System.out.println("Max memory JVM will attempt to use: " + (runtime.maxMemory() / ONE_MB) +" Mb");

System.out.println("Total memory in JVM: " + (runtime.totalMemory() / ONE_MB) +" Mb");

}

}

which prints

$ java TestMem

Version: 1.5.0_04-b05

VM: Java HotSpot(TM) Client VM

Available processors: 2

Max memory JVM will attempt to use: 63 Mb

Total memory in JVM: 1 Mb

clearly showing that Java can see that there are 2 processors. Perhaps it is not detecting the memory?

Any insight would be appreciated,

Tim

[3193 byte] By [timmorrowa] at [2007-11-26 20:09:52]
# 1
FWIW Same issue on Jdk1.6:$ java TestMemVersion: 1.6.0-b105VM: Java HotSpot(TM) Client VMAvailable processors: 2Max memory JVM will attempt to use: 63 MbTotal memory in JVM: 4 Mb
timmorrowa at 2007-7-9 23:13:10 > top of Java-index,Desktop,Runtime Environment...
# 2

It would seem that the system is actual a dual core Xeon. It appears the detection logic (j2se/src/solaris/bin/java_md.c) checks for the number of logical processors in the following scenarios:

* Processor is Pentium 4 family, Genuine Intel and has Hyperthreading enabled.

I have a Core Duo laptop that is "server-class". Since it does not report to be "Pentium 4 family", no hyperthreading check is done hence no logical processor check is done hence it believes I have 2 CPUs.

That appears to be a flaw. Limiting the check for hyperthreading/logical processors to "Pentium 4 family" only seems to be the wrong thing to do.

timmorrowa at 2007-7-9 23:13:10 > top of Java-index,Desktop,Runtime Environment...
# 3

As a first step, see whether the "java" launcher thinks you have a server-class machine: $ _JAVA_LAUNCHER_DEBUG=1 ./bin/java -version

-_JAVA_LAUNCHER_DEBUG-

....

pages: 1021739 page_size: 4096 physical memory: 4185042944 (3.898GB)

sysconf(_SC_NPROCESSORS_CONF): 2

vendor: G e n u i n e I n t e l

value_of_eax: 0x6b1 value_of_edx: 0x383fbff

not Pentium 4 or extended

physical processors: 2

linux_i386_ServerClassMachine: true

Default VM: server

Does `..../linux-i586/jre/lib/i386/server/libjvm.so' exist ... yes.

....

java version "1.6.0"

Java(TM) SE Runtime Environment (build 1.6.0-b105)

Java HotSpot(TM) Server VM (build 1.6.0-b105, mixed mode)

where you can see it feeling around to see how much memory it has an whether it is on a real multiprocessor or not.

If you have the fastdebug version of the JVM, you could run that as$ ./fastdebug/bin/java -XX:+PrintMiscellaneous -XX:+Verbose -version

VM option '+PrintMiscellaneous'

VM option '+Verbose'

....

CPU:total 2 family 6, cmov, cx8, fxsr, mmx, sse

Logical CPUs per package: 1

....

java version "1.6.0-fastdebug"

Java(TM) SE Runtime Environment (build 1.6.0-fastdebug-b105)

Java HotSpot(TM) Server VM (build 1.6.0-fastdebug-b105-debug, mixed mode)

where you can see the JVM itself going through the same tests.

If the launcher thinks you are on a server-class machine but the JVM doesn't, you should get a server JVM with the non-server settings for the garbage collector and heap size. Since you are failing to get the server JVM, I suspect you are failing one of the launcher tests.

PeterKesslera at 2007-7-9 23:13:10 > top of Java-index,Desktop,Runtime Environment...
# 4

Thanks for the response.

I did discover that _JAVA_LAUNCHER_DEBUG variable only after posting this. It does give valuable information.

here is the result of doing that on the dual Xeon processor machine:

pages: 1038870 page_size: 4096 physical memory: 4255211520 (3.963GB)

sysconf(_SC_NPROCESSORS_CONF): 2

vendor: G e n u i n e I n t e l

value_of_eax: 0xf29 value_of_edx: 0xbfebfbff

Hyperthreading supported

logical processors per package: 2

physical processors: 1

linux_i386_ServerClassMachine: false

Default VM: client

From poking around the detection code (I'm no C programmer, but I think I understand what it is doing) it seems to compute physical processors as:

sysconf(_SC_NPROCESSORS_CONF) / logical processors per package

in this case: 2 / 2 = 1

Ironically on my Intel Core Duo (single CPU, dual core) Linux laptop, here is the output:

pages: 518711 page_size: 4096 physical memory: 2124640256 (1.979GB)

sysconf(_SC_NPROCESSORS_CONF): 2

vendor: G e n u i n e I n t e l

value_of_eax: 0x6e8 value_of_edx: 0xbfe9fbff

not Pentium 4 or extended

physical processors: 2

linux_i386_ServerClassMachine: true

Default VM: server

Again, from poking around the detection code it only checks for "logical processors" if CPUID reports that hyperthreading is enabled. It only checks for hyperthreading if CPUID responds with a "Pentium 4 family". If I understand correctly Pentium 4 family is the "f" in value_of_eax: 0xf29 for the Xeon processors.

So in summary, the things that surprised me are:

* Only check logical processors / hyperthreading if Pentium 4 family

* For a dual cpu Xeon, number of processors = 2 and logical processors per package = 2 but that should not imply 1 physical processor.

I did confirm with our systems people that the Xeon machine really is dual CPU.

Thanks for your assistance.

Tim

timmorrowa at 2007-7-9 23:13:10 > top of Java-index,Desktop,Runtime Environment...