【问题标题】:How does Java 7 decide on the max value of heap memory allocated (-Xmx) on OSXJava 7 如何决定 OSX 上分配的堆内存的最大值 (-Xmx)
【发布时间】:2013-11-11 19:24:42
【问题描述】:

如果未在 OSX 捆绑包中指定,Java 7 如何确定分配的堆内存的最大值 (-Xmx),我已阅读手册页并没有给出任何指示。它的分配似乎比 Java 6 上的默认值多,我想知道它是否随机器上可用的内存而变化,这对我来说非常有用,因为我的应用程序受内存限制,但我不能将默认值设置得太高,因为那时该应用程序将无法在较低规格的机器上运行。

【问题讨论】:

  • System.out.println(Runtime.getRuntime().maxMemory());
  • 我知道如何获取值,但我不明白它如何决定将值设置为什么。

标签: java macos java-7


【解决方案1】:

openjdk 源代码hotspot/src/share/vm/runtime/arguments.cpp的默认堆大小

从源代码复制评论

  // 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.

分数 = 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")              \

关于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);
  }
}

【讨论】:

  • 谢谢,这很有用,虽然很高兴了解它确实使用了多少物理内存。这也是 openjdk,Oracle 构建实际上做同样的事情,这是否也适用于 Windows 构建。
  • @PaulTaylor oracle 和 openjdk 的不同 stackoverflow.com/questions/17360011/…
  • 如果有办法设置比例,基本上它最多占物理内存的四分之一?
猜你喜欢
  • 2018-05-02
  • 2010-11-14
  • 2012-12-06
  • 2019-10-13
  • 1970-01-01
  • 2021-11-17
  • 2016-07-18
  • 1970-01-01
  • 2017-11-22
相关资源
最近更新 更多