堆的参数调优

首先回顾下Java7/8之间的堆内存模型和差别

堆的参数调优_第1张图片
JAVA8中:Perm变成元空间;

如果你运行程序慢,和经常出现OOM错误,我们可以先测试进行堆的参数调优;

通过Runtime.getRuntime().maxMemory()/totalMemory 我们可以考到java的总内存和初始内存;
默认来说:
jvm启动的初始内存是:你的内存/64
jvm的最大内存大小:你的内存/4

开始对的参数调优:

-Xms 初始内存大小 本机内存/64
-Xmx 最大内存大小 本机内存/64

在idea中调节VM参数: -Xms1024m -Xmx1024m -XX:+PrintGCDetails

  • PrintGCDetails输出详细的内存分布情况
    调节后后运行代码与结果:
    堆的参数调优_第2张图片
  • 在实际汇总也可以看出 养老区是新生区要大; 各区内存的分布情况也可以看的很详细;
  • 我的jdk版本是8;和7对比的是 不一样的是8中的永久是是metaspace=元空间区;看下面java7种的永久区是
    PSPermGen区 是永久区
  • 7的运行结果是:
    堆的参数调优_第3张图片

现在我们测试堆溢出的情况:

循环无限使用,
调小虚拟机内存,等待不用那么久才爆
在这里插入图片描述
可以看到这串代码,我们无限加长字符串str,且缩小了堆的容量,所以堆的溢出是很快的,因为str一直在使用着,在gc下一直幸,同时大小也是不断变大;

  • 从结果中可以看到:
    堆的参数调优_第4张图片
    可以看到,str在新生区的Eden区只是经历了几次gc就直接报错溢出;
    从一开始的gc 轻量级回收 到fullgc到gc到full gc
    可以看到gc并没有到15次,就进行了full gc,而fullgc是在养老区进行的gc;

为什么这么快到养老区:主要是我们设置的太小了内存,伊甸区存储的对象大,存储不进幸存区的,所以就直接进入养老区;伊甸区当达到一定的量就会触发gc;
想想除了调高内存缓解养老区的溢出还有啥方法:
调高进入养老区的条件,比如得在幸存区 幸存gc的次数调高

你可能感兴趣的:(JVM,jvm)