美文网首页
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());
      }
    }
  }
}

相关文章

  • spark私房笔记

    集群内存计算平台。 0 java环境准备 jdk1.8rpm -ivh jdk-8u92-linux-x64.rp...

  • 搭建ELK

    一、部署ES集群 1、安装JDK 2、安装配置ES 3、设置堆大小 确保堆内存最小值(Xms)与最大值(Xmx)的...

  • tomcat性能优化

    优化内存 /bin/catalina.sh添加JAVA_OPTS参数jdk1.7 jdk1.8 1.8版本中已经没...

  • jvm内存模型

    一、内存区域 堆 直接内存 方法区1.8之前实现是永久代,在堆中。1.8之后改成了元数据空间,放到了直接内存。运行...

  • hadoop3.0新特性

    1、概要 1. 基于jdk1.8(最低版本要求) 2. mr采用基于内存的计算,提升性能(快spark 10倍) ...

  • JVM内存结构

    Java 虚拟机的内存空间分为 5 个部分:程序计数器、Java虚拟机栈、本地方法栈、堆、方法区。 JDK 1.8...

  • Java虚拟机理解-内存管理

    运行时数据区域 jdk 1.8之前与之后的内存模型有差异,方法区有变化(https://cloud.tencent...

  • 堆外内存整理

    堆外内存, JDK 1.4 nio引进了ByteBuffer.allocateDirect()分配堆外内存 Byt...

  • JVM内存模型&JAVA内存模型

    JVM虚拟机内存区域概况 这里介绍的是JDK1.8 JVM运行时内存数据区域划分。1.8同1.7比,最大的差别就是...

  • JDK的安装步骤

    (我用的jdk是1.8的) 1,创建jdk1.8文件夹 2,在jdk1.8文件夹里面创建jdk与jre文件夹并将安...

网友评论

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

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