3

How does Java 7 decide on the max value of heap memory allocated (-Xmx) if not specified on an OSX bundle, I've read the manual page and it gave no indication. It seems to be allocated more than the default on Java 6 and I wonder if it varies with the memory available on the machine, that would be very useful to me because my application is memory bound, but I cannot set the default too high because then the application would fail to run at all on lower specification machines.

Paul Taylor
  • 13,411
  • 42
  • 184
  • 351

1 Answers1

3

default heap size from openjdk source code hotspot/src/share/vm/runtime/arguments.cpp

copy comment from source

  // If the maximum heap size has not been set with -Xmx,
  // then set it as fraction of the size of physical memory,
  // respecting the maximum and minimum sizes of the heap.

Fraction = 4

  product(uintx, MaxRAMFraction, 4,                                         \
          "Maximum fraction (1/n) of real memory used for maximum heap "    \
          "size")                                                           \
                                                                            \
  product(uintx, DefaultMaxRAMFraction, 4,                                  \
          "Maximum fraction (1/n) of real memory used for maximum heap "    \
          "size; deprecated: to be renamed to MaxRAMFraction")              \

full code about mx

void Arguments::set_heap_size() {
  if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) {
    // Deprecated flag
    FLAG_SET_CMDLINE(uintx, MaxRAMFraction, DefaultMaxRAMFraction);
  }

  const julong phys_mem =
    FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM)
                            : (julong)MaxRAM;

  // If the maximum heap size has not been set with -Xmx,
  // then set it as fraction of the size of physical memory,
  // respecting the maximum and minimum sizes of the heap.
  if (FLAG_IS_DEFAULT(MaxHeapSize)) {
    julong reasonable_max = phys_mem / MaxRAMFraction;

    if (phys_mem <= MaxHeapSize * MinRAMFraction) {
      // Small physical memory, so use a minimum fraction of it for the heap
      reasonable_max = phys_mem / MinRAMFraction;
    } else {
      // Not-small physical memory, so require a heap at least
      // as large as MaxHeapSize
      reasonable_max = MAX2(reasonable_max, (julong)MaxHeapSize);
    }
    if (!FLAG_IS_DEFAULT(ErgoHeapSizeLimit) && ErgoHeapSizeLimit != 0) {
      // Limit the heap size to ErgoHeapSizeLimit
      reasonable_max = MIN2(reasonable_max, (julong)ErgoHeapSizeLimit);
    }
    if (UseCompressedOops) {
      // Limit the heap size to the maximum possible when using compressed oops
      julong max_coop_heap = (julong)max_heap_for_compressed_oops();
      if (HeapBaseMinAddress + MaxHeapSize < max_coop_heap) {
        // Heap should be above HeapBaseMinAddress to get zero based compressed oops
        // but it should be not less than default MaxHeapSize.
        max_coop_heap -= HeapBaseMinAddress;
      }
      reasonable_max = MIN2(reasonable_max, max_coop_heap);
    }
    reasonable_max = os::allocatable_physical_memory(reasonable_max);

    if (!FLAG_IS_DEFAULT(InitialHeapSize)) {
      // An initial heap size was specified on the command line,
      // so be sure that the maximum size is consistent.  Done
      // after call to allocatable_physical_memory because that
      // method might reduce the allocation size.
      reasonable_max = MAX2(reasonable_max, (julong)InitialHeapSize);
    }

    if (PrintGCDetails && Verbose) {
      // Cannot use gclog_or_tty yet.
      tty->print_cr("  Maximum heap size " SIZE_FORMAT, reasonable_max);
    }
    FLAG_SET_ERGO(uintx, MaxHeapSize, (uintx)reasonable_max);
  }

  // If the initial_heap_size has not been set with InitialHeapSize
  // or -Xms, then set it as fraction of the size of physical memory,
  // respecting the maximum and minimum sizes of the heap.
  if (FLAG_IS_DEFAULT(InitialHeapSize)) {
    julong reasonable_minimum = (julong)(OldSize + NewSize);

    reasonable_minimum = MIN2(reasonable_minimum, (julong)MaxHeapSize);

    reasonable_minimum = os::allocatable_physical_memory(reasonable_minimum);

    julong reasonable_initial = phys_mem / InitialRAMFraction;

    reasonable_initial = MAX2(reasonable_initial, reasonable_minimum);
    reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize);

    reasonable_initial = os::allocatable_physical_memory(reasonable_initial);

    if (PrintGCDetails && Verbose) {
      // Cannot use gclog_or_tty yet.
      tty->print_cr("  Initial heap size " SIZE_FORMAT, (uintx)reasonable_initial);
      tty->print_cr("  Minimum heap size " SIZE_FORMAT, (uintx)reasonable_minimum);
    }
    FLAG_SET_ERGO(uintx, InitialHeapSize, (uintx)reasonable_initial);
    set_min_heap_size((uintx)reasonable_minimum);
  }
}
farmer1992
  • 7,816
  • 3
  • 30
  • 26
  • Thanks that useful, although it would be nice to understand quite what fraction of physical memory it does use. Also this is openjdk do the Oracle builds actually do the same thing and does this also apply to Windows builds now. – Paul Taylor Oct 31 '13 at 19:42
  • @PaulTaylor different between oracle and openjdk http://stackoverflow.com/questions/17360011/technically-what-is-the-main-difference-between-oracle-jdk-and-open-jdk – farmer1992 Nov 01 '13 at 02:17
  • So basically its upto quarter of physical memory I winder if there is a way to set the proportion ? – Paul Taylor Nov 03 '13 at 20:57