继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

java容器内存识别

xpbob
关注TA
已关注
手记 152
粉丝 1.6万
获赞 380

内存识别

在没有设置内存参数的时候,如何没有设置xms,xmx

void Arguments::set_heap_size() {
  julong phys_mem;

  // If the user specified one of these options, they
  // want specific memory sizing so do not limit memory
  // based on compressed oops addressability.
  // Also, memory limits will be calculated based on
  // available os physical memory, not our MaxRAM limit,
  // unless MaxRAM is also specified.
  bool override_coop_limit = (!FLAG_IS_DEFAULT(MaxRAMPercentage) ||
                           !FLAG_IS_DEFAULT(MaxRAMFraction) ||
                           !FLAG_IS_DEFAULT(MinRAMPercentage) ||
                           !FLAG_IS_DEFAULT(MinRAMFraction) ||
                           !FLAG_IS_DEFAULT(InitialRAMPercentage) ||
                           !FLAG_IS_DEFAULT(InitialRAMFraction) ||
                           !FLAG_IS_DEFAULT(MaxRAM));
  if (override_coop_limit) {
    if (FLAG_IS_DEFAULT(MaxRAM)) {
      phys_mem = os::physical_memory();
      FLAG_SET_ERGO(MaxRAM, (uint64_t)phys_mem);
    } else {
      phys_mem = (julong)MaxRAM;
    }
  } else {
    phys_mem = FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM)
                                       : (julong)MaxRAM;
  }




 if (FLAG_IS_DEFAULT(MaxHeapSize)) {
  julong reasonable_max = (julong)((phys_mem * MaxRAMPercentage) / 100);
    const julong reasonable_min = (julong)((phys_mem * MinRAMPercentage) / 100);

}
  if (FLAG_IS_DEFAULT(MaxRAMPercentage) &&
      !FLAG_IS_DEFAULT(MaxRAMFraction))
    MaxRAMPercentage = 100.0 / MaxRAMFraction;
  product(uintx, MaxRAMFraction, 4,                                         \
          "Maximum fraction (1/n) of real memory used for maximum heap "    \
          "size. "                                                          \
          "Deprecated, use MaxRAMPercentage instead")                       \
          range(1, max_uintx)   

MaxRAMPercentage在没有设置的情况下是根据MaxRAMFraction计算的,默认MaxRAMFraction是4。这也是xmx默认是内存的四分之一。

  if (FLAG_IS_DEFAULT(MinRAMPercentage) &&
      !FLAG_IS_DEFAULT(MinRAMFraction))
    MinRAMPercentage = 100.0 / MinRAMFraction;
 product(uintx, MinRAMFraction, 2,                                         \
          "Minimum fraction (1/n) of real memory used for maximum heap "    \
          "size on systems with small physical memory size. "               \
          "Deprecated, use MinRAMPercentage instead")                       \
          range(1, max_uintx)  
    julong reasonable_max = (julong)((phys_mem * MaxRAMPercentage) / 100);
    const julong reasonable_min = (julong)((phys_mem * MinRAMPercentage) / 100);
    if (reasonable_min < MaxHeapSize) {
      // Small physical memory, so use a minimum fraction of it for the heap
      reasonable_max = reasonable_min;
    } else {
      // Not-small physical memory, so require a heap at least
      // as large as MaxHeapSize
      reasonable_max = MAX2(reasonable_max, (julong)MaxHeapSize);
    }
  product(size_t, MaxHeapSize, ScaleForWordSize(96*M),                      \
          "Maximum heap size (in bytes)")                                   \
          constraint(MaxHeapSizeConstraintFunc,AfterErgo)   

MaxHeapSize默认96m,所以现在的机型上不会出现reasonable_min的情况,所以看到的heap都是四分之一。

  if (InitialHeapSize == 0 || MinHeapSize == 0) {
    julong reasonable_minimum = (julong)(OldSize + NewSize);

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

    reasonable_minimum = limit_heap_by_allocatable_memory(reasonable_minimum);

    if (InitialHeapSize == 0) {
      julong reasonable_initial = (julong)((phys_mem * InitialRAMPercentage) / 100);
      reasonable_initial = limit_heap_by_allocatable_memory(reasonable_initial);

      reasonable_initial = MAX3(reasonable_initial, reasonable_minimum, (julong)MinHeapSize);
      reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize);

      FLAG_SET_ERGO(InitialHeapSize, (size_t)reasonable_initial);
      log_trace(gc, heap)("  Initial heap size " SIZE_FORMAT, InitialHeapSize);
    }
    // If the minimum heap size has not been set (via -Xms or -XX:MinHeapSize),
    // synchronize with InitialHeapSize to avoid errors with the default value.
    if (MinHeapSize == 0) {
      FLAG_SET_ERGO(MinHeapSize, MIN2((size_t)reasonable_minimum, InitialHeapSize));
      log_trace(gc, heap)("  Minimum heap size " SIZE_FORMAT, MinHeapSize);
    }
 if (FLAG_IS_DEFAULT(InitialRAMPercentage) &&
      !FLAG_IS_DEFAULT(InitialRAMFraction))
    InitialRAMPercentage = 100.0 / InitialRAMFraction;

  product(uintx, InitialRAMFraction, 64,                                    \
          "Fraction (1/n) of real memory used for initial heap size. "      \
          "Deprecated, use InitialRAMPercentage instead")                   \
          range(1, max_uintx)     

JVM 会大概根据检测到的内存大小,设置最初启动时的堆大小为系统内存的 1/64;并将堆最大值,设置为系统内存的 1/4。

julong os::physical_memory() {
  jlong phys_mem = 0;
  if (OSContainer::is_containerized()) {
    jlong mem_limit;
    if ((mem_limit = OSContainer::memory_limit_in_bytes()) > 0) {
      log_trace(os)("total container memory: " JLONG_FORMAT, mem_limit);
      return mem_limit;
    }
    log_debug(os, container)("container memory limit %s: " JLONG_FORMAT ", using host value",
                            mem_limit == OSCONTAINER_ERROR ? "failed" : "unlimited", mem_limit);
  }

  phys_mem = Linux::physical_memory();
  log_trace(os)("total system memory: " JLONG_FORMAT, phys_mem);
  return phys_mem;
}

在容器的情况下physical_memory返回的是memory_limit_in_bytes。所以这个值会作为我们设置默认heap值的指标。

现有的问题

问题1

jmx getProcessCpuTime指标在使用share mode的时候,运行一段时间会返回-1。
目前这个bug已经在19,17,11上修复。但是jdk8的还没修复。pr还没有被review
https://github.com/openjdk/jdk8u-dev/pull/105
很有可能无法进入jdk8的分支。也就是说jdk8上想规避这个问题,最好就是不用share mode或者直接升级jdk。

问题2

当在容器环境下,jvm启动不检测xmx是否有效。jvm进程设置了xmx,但是内存默认是懒加载,所以不会里面占用那么多,但容器给不了那么多的资源,最后会在运行时被kill掉。如果改成提前加载的模式 -XX:+AlwaysPreTouch,在启动时就知道heap的内存是否足够。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP