美文网首页
JDK 1.8 堆内存设置与计算

JDK 1.8 堆内存设置与计算

作者: starskye | 来源:发表于2023-06-26 00:34 被阅读0次

    计算堆的最大值与堆的最小值MaxHeapSize,InitialHeapSize,min_heap_size的计算原理

    void Arguments::set_heap_size() {
      //RAMFraction 使用对内存的百分比,比如当前内存是1G而百分比是4则计算结果为256M而256M便是我们使用堆的最大内存
      //此处默认值若被修改则同步到MaxRAMFraction
      if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) {
        // Deprecated flag
        FLAG_SET_CMDLINE(uintx, MaxRAMFraction, DefaultMaxRAMFraction);
      }
      //获取当前系统物理内存总大小其中MaxRAM是默认1G(在32位内),取其中的最小值作为堆的最大内存,假设当期机器为4G则此处为1G,因为取最小值
      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)) {
        //首先计算前方设置的百分比与总物理内存得出我们能使用的最大内存值
        //MaxRAMFraction默认为4得到256M(延续上文的1G
        julong reasonable_max = phys_mem / MaxRAMFraction;
        //MaxHeapSize=ScaleForWordSize(96*M)=(96*M) * 13 / 10 &0xfffffff0
        //MinRAMFraction = 2
        //总的结果:大概是130M*2 是否大于等于上方获取的物理内存,若大于则重新计算,因为jvm的使用一定不允许打过物理内存的限制
        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
          //若设置了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 = limit_by_allocatable_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 limit_by_allocatable_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 minimum or initial heap_size have not been set or requested to be set
      // ergonomically, set them accordingly.
      //若未设置堆的初始值则计算堆的初始值
      if (InitialHeapSize == 0 || min_heap_size() == 0) {
        //Old与New默认为4M+1M此处reasonable_minimum为5M
        julong reasonable_minimum = (julong)(OldSize + NewSize);
        //此处必然是5M,因为最大堆内存是1G
        reasonable_minimum = MIN2(reasonable_minimum, (julong)MaxHeapSize);
        //5M
        reasonable_minimum = limit_by_allocatable_memory(reasonable_minimum);
        if (InitialHeapSize == 0) {
          //InitialRAMFraction默认是64,phys_mem为1G 初始值为16M
          julong reasonable_initial = phys_mem / InitialRAMFraction;
          //-Xms 设置的min_heap_size 默认为0,此处取0M 16M 5M的最大值,得到结果为16M
          reasonable_initial = MAX3(reasonable_initial, reasonable_minimum, (julong)min_heap_size());
          //初始化内存与最大内存谁小,谁做初始内存
          reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize);
          //当前初始化内存是否支持分配
          reasonable_initial = limit_by_allocatable_memory(reasonable_initial);
          if (PrintGCDetails && Verbose) {
            // Cannot use gclog_or_tty yet.
            tty->print_cr("  Initial heap size " SIZE_FORMAT, (uintx)reasonable_initial);
          }
          //设置初始化
          FLAG_SET_ERGO(uintx, InitialHeapSize, (uintx)reasonable_initial);
        }
        // If the minimum heap size has not been set (via -Xms),
        // synchronize with InitialHeapSize to avoid errors with the default value.
        //若未设置堆的最小值,则设置获取最小值作为堆的最小值
        if (min_heap_size() == 0) {
          set_min_heap_size(MIN2((uintx)reasonable_minimum, InitialHeapSize));
          if (PrintGCDetails && Verbose) {
            // Cannot use gclog_or_tty yet.
            tty->print_cr("  Minimum heap size " SIZE_FORMAT, min_heap_size());
          }
        }
      }
    }
    

    相关文章

      网友评论

          本文标题:JDK 1.8 堆内存设置与计算

          本文链接:https://www.haomeiwen.com/subject/biqgzrtx.html