JDK-8006431 : os::Bsd::initialize_system_info() sets _physical_memory too large
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2013-01-16
  • Updated: 2014-06-26
  • Resolved: 2013-01-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 Other
7u40Fixed 8Fixed hs24Fixed
On my 8GB OSX laptop os::Bsd::initialize_system_info()  sets up _physical_memory to be 140733629517824, which is 127TB.

Since we base for example the maximum Java heap size on os::physical_memory() which on BSD returns this value we get ~30GB max heap size even for just running "java -version".

Here is the code in os::Bsd::initialize_system_info() that returns a too large value:

  mib[0] = CTL_HW;
  mib[1] = HW_USERMEM;
  len = sizeof(mem_val);
  if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1) 
       _physical_memory = mem_val;

Somehow the sysctl() call sets mem_val to 140733629517824.

Impact=Medium since we normally don't crash but just use up much more memory than necessary (we don't commit the maximum heap size, but there are several data structures that are O(MaxHeapSize) in size.
Likelihood: High. Seem to happen on all OSX machine where I've tried it.
Workaround: Low. Set -Xmx on the command line.

Man page for sysctl: https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/sysctl.3.html HW_MEMSIZE is the 64 bit value we want.

Staffan, you are correct. Changing from HW_USERMEM to HW_MEMSIZE, gives me 8GB in mem_val instead of 127TB. This is correct on my machine and it also gives me a default maximum heap size of 2 GB instead of 30GB.

I think mem_val should be an int, not a u_long. (You can see the value with "sysctl hw.usermem" on the command line). But on the other hand, that means it's not really going to work if you have lots of memory... Most likely it is HW_MEMSIZE we want, which is documented as a 64-bit value.