简介

jdk8的元空间的初始大小是21M,如果启动后GC过于频繁,请将该值设置得大一些。

如果应用启动时,FGC出现了,可能是由于metaspace导致,例如:

从JDK8开始,永久代(PermGen)的概念被废弃掉了,取而代之的是一个称为Metaspace的存储空间。Metaspace使用的是本地内存,而不是堆内存,也就是说在默认情况下Metaspace的大小只与本地内存大小有关。当然你也可以通过以下的几个参数对Metaspace进行控制:

-XX:MetaspaceSize=N :这个参数是初始化的Metaspace大小,该值越大触发Metaspace GC的时机就越晚。随着GC的到来,虚拟机会根据实际情况调控Metaspace的大小,可能增加上线也可能降低。在默认情况下,这个值大小根据不同的平台在12M到20M浮动。使用java -XX:+PrintFlagsInitial命令查看本机的初始化参数,-XX:Metaspacesize为21810376B(大约20.8M)。

-XX:MaxMetaspaceSize=N :这个参数用于限制Metaspace增长的上限,防止因为某些情况导致Metaspace无限的使用本地内存,影响到其他程序。默认无上限。

-XX:MinMetaspaceFreeRatio=N :当进行过Metaspace GC之后,会计算当前Metaspace的空闲空间比,如果空闲比小于这个参数,那么虚拟机将增长Metaspace的大小。在本机该参数的默认值为40,也就是40%。设置该参数可以控制Metaspace的增长的速度,太小的值会导致Metaspace增长的缓慢,Metaspace的使用逐渐趋于饱和,可能会影响之后类的加载。而太大的值会导致Metaspace增长的过快,浪费内存。

-XX:MaxMetasaceFreeRatio=N :当进行过Metaspace GC之后, 会计算当前Metaspace的空闲空间比,如果空闲比大于这个参数,那么虚拟机会释放Metaspace的部分空间。在本机该参数的默认值为70,也就是70%。

-XX:MaxMetaspaceExpansion=N :Metaspace增长时的最大幅度。在本机上该参数的默认值为5452592B(大约为5MB)。

-XX:MinMetaspaceExpansion=N :Metaspace增长时的最小幅度。在本机上该参数的默认值为340784B(大约330KB为)。

一个误解

使用jstat -gcutil的结果中的M代表的是元空间的使用比例。又例如:测试环境上某个服务为例,配置了-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m,通过jstat -gcutil pid查看M的值为98.32,即Meta区使用率也达到了98.32%:

然后,再通过jstat -gc 4210 2s 3命名查看,结果如下图所示,计算MU/MC即Meta区的使用率确实达到了98.32%,但是MC,即Metaspace Capacity只有55296k,并不是参数MetaspaceSize指定的256m:

那么-XX:MetaspaceSize=256m的含义到底是什么呢?其实,这个JVM参数是指Metaspace扩容时触发FullGC的初始化阈值,也是最小的阈值。这里有几个要点需要明确:

如果没有配置-XX:MetaspaceSize,那么触发FGC的阈值是21807104(约20.8m),可以通过jinfo -flag MetaspaceSize pid得到这个值;jps -v也可以查看jvm的参数设置情况。

如果配置了-XX:MetaspaceSize,那么触发FGC的阈值就是配置的值;

Metaspace由于使用不断扩容到-XX:MetaspaceSize参数指定的量,就会发生FGC;且之后每次Metaspace扩容都可能会发生FGC(至于什么时候会,比较复杂,跟几个参数有关);

如果Old区配置CMS垃圾回收,那么扩容引起的FGC也会使用CMS算法进行回收;

如果MaxMetaspaceSize设置太小,可能会导致频繁FullGC,甚至OOM;

建议

MetaspaceSize和MaxMetaspaceSize设置一样大;

具体设置多大,建议稳定运行一段时间后通过jstat -gc pid确认且这个值大一些,对于大部分项目256m即可。

测试代码

下面会针对这个参数对Metaspace做一个粗略的展示。

importjava.util.ArrayList;importjava.util.List;importorg.objectweb.asm.ClassWriter;importorg.objectweb.asm.MethodVisitor;importorg.objectweb.asm.Opcodes;/** 继承ClassLoader是为了方便调用defineClass方法,因为该方法的定义为protected

**/

public class Metaspace extendsClassLoader {public static voidmain(String[] args) {//类持有

List> classes = new ArrayList>();//循环1000w次生成1000w个不同的类。

for (int i = 0; i < 10000000; ++i) {

ClassWriter cw= new ClassWriter(0);//定义一个类名称为Class{i},它的访问域为public,父类为java.lang.Object,不实现任何接口

cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "Class" + i, null,"java/lang/Object", null);//定义构造函数方法

MethodVisitor mw = cw.visitMethod(Opcodes.ACC_PUBLIC, "","()V", null, null);//第一个指令为加载this

mw.visitVarInsn(Opcodes.ALOAD, 0);//第二个指令为调用父类Object的构造函数

mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object","", "()V", false);//第三条指令为return

mw.visitInsn(Opcodes.RETURN);

mw.visitMaxs(1, 1);

mw.visitEnd();

Metaspace test= newMetaspace();byte[] code =cw.toByteArray();//定义类

Class> exampleClass = test.defineClass("Class" + i, code, 0, code.length);

classes.add(exampleClass);

}

}

}

上面的程序的大致意思是,不断的生成新的类, 然后让类加载器去加载这个类,同时将其保存下来,避免GC回收掉。这里使用到了ASM框架

测试参数

在运行该程序的时候加上如下的JVM参数,第一个参数用于打印GC日志,第二个参数用于打印对应的时间戳。

-XX:+PrintGCDetails -XX:+PrintGCDateStamps

运行程序后,打印出的第一行日志显示,

2015-07-05T16:26:53.708+0800: [GC (Metadata GC Threshold) [PSYoungGen: 13978K->3229K(38400K)] 13978K->3237K(125952K), 0.0043062 secs] [Times: user=0.06 sys=0.02, real=0.00secs]2015-07-05T16:26:53.712+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 3229K->0K(38400K)] [ParOldGen: 8K->3111K(60928K)] 3237K->3111K(99328K), [Metaspace: 5699K->5699K(1064960K)], 0.0110314 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

奇怪的事情发生了,这里面显示的Metaspace大小为1064960K,将近1G,而不是前面提到的默认值20M左右。继续运行一段时间后出现了如下的异常,

Exception in thread "main" java.lang.OutOfMemoryError: Compressed classspace

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:760)

at java.lang.ClassLoader.defineClass(ClassLoader.java:642)

at Metaspace.main(Metaspace.java:37)

根据http://itdoc.hitachi.co.jp/manuals/link/has_v101001/0344211De/compressedclassspacesize.htm

的描述,在JVM使用-XX:+UseCompressedClassPointers和-XX:+UseCompressedOops开启Compressed

Class的功能后,会在Metaspace中开辟出一块新的空间(Compressed Class

Space),上面的错误正是由于这个空间出现了OutOfMemory,可以通过设置-XX:CompressedClassSpaceSize(默认值为1G)的大小或者-XX:-UseCompressedClassPointers来关闭该功能。

为了不影响下面的测试,暂时使用-XX:-UseCompressedClassPointers来关闭。

这时JVM参数变为了,

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:-UseCompressedClassPointers

再一次运行程序,出现如下日志

2015-07-05T17:38:31.030+0800: [GC (Metadata GC Threshold) [PSYoungGen: 21301K->4984K(38400K)] 21301K->4992K(125952K), 0.0041727 secs] [Times: user=0.00 sys=0.00, real=0.00secs]2015-07-05T17:38:31.034+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 4984K->0K(38400K)] [ParOldGen: 8K->4789K(64512K)] 4992K->4789K(102912K), [Metaspace: 6922K->6922K(22528K)], 0.0147936 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]

初始的Metaspace的大小变为了20M左右。由此猜想之前出现的问题是不是由于开启了压缩功能,而默认值-XX:CompressedClassSpaceSize=1G,其大于-XX:MetaspaceSize=20M,所以MetaspaceSize被设置为了1G。

-XX:MetaspaceSize的使用

添加JVM参数,-XX:MetaspaceSize=100m, 这时的JVM参数变为,

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:-UseCompressedClassPointers -XX:MetaspaceSize=50M

运行后出现的日志为,

2015-07-05T17:53:20.430+0800: [GC (Allocation Failure) [PSYoungGen: 33280K->5100K(38400K)] 33280K->7635K(125952K), 0.0076185 secs] [Times: user=0.03 sys=0.03, real=0.01secs]2015-07-05T17:53:20.511+0800: [GC (Metadata GC Threshold) [PSYoungGen: 24676K->5102K(71680K)] 27211K->11885K(159232K), 0.0085707 secs] [Times: user=0.00 sys=0.00, real=0.01secs]2015-07-05T17:53:20.519+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 5102K->0K(71680K)] [ParOldGen: 6782K->11703K(67584K)] 11885K->11703K(139264K), [Metaspace: 13581K->13581K(51200K)], 0.0442425 secs] [Times: user=0.19 sys=0.00, real=0.04 secs]

默认的初始值变为了50M,可见设置的参数生效了。

-XX:MaxMetaspaceSize的使用

添加JVM参数,-XX:MaxMetaspaceSize=100m, 这时的JVM参数变为,

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:-UseCompressedClassPointers -XX:MetaspaceSize=50M -XX:MaxMetaspaceSize=100m

运行后出现的日志为,

2015-07-05T18:04:10.000+0800: [GC (Allocation Failure) [PSYoungGen: 33280K->5116K(38400K)] 33280K->7627K(125952K), 0.0069565 secs] [Times: user=0.08 sys=0.00, real=0.01secs]2015-07-05T18:04:10.086+0800: [GC (Metadata GC Threshold) [PSYoungGen: 24689K->5102K(71680K)] 27199K->11917K(159232K), 0.0092239 secs] [Times: user=0.00 sys=0.00, real=0.01secs]2015-07-05T18:04:10.095+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 5102K->0K(71680K)] [ParOldGen: 6814K->11703K(74240K)] 11917K->11703K(145920K), [Metaspace: 13581K->13581K(51200K)], 0.0636790 secs] [Times: user=0.20 sys=0.00, real=0.06secs]2015-07-05T18:04:10.297+0800: [GC (Metadata GC Threshold) [PSYoungGen: 37664K->5106K(71680K)] 49367K->19785K(145920K), 0.0066032 secs] [Times: user=0.11 sys=0.00, real=0.01secs]2015-07-05T18:04:10.304+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 5106K->0K(71680K)] [ParOldGen: 14679K->19664K(129536K)] 19785K->19664K(201216K), [Metaspace: 21181K->21181K(86016K)], 0.0752276 secs] [Times: user=0.45 sys=0.02, real=0.08secs]2015-07-05T18:04:10.454+0800: [GC (Metadata GC Threshold) [PSYoungGen: 19414K->4219K(82432K)] 39079K->23884K(211968K), 0.0048493 secs] [Times: user=0.11 sys=0.00, real=0.01secs]2015-07-05T18:04:10.459+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 4219K->0K(82432K)] [ParOldGen: 19664K->23672K(187392K)] 23884K->23672K(269824K), [Metaspace: 24981K->24981K(102400K)], 0.0569726 secs] [Times: user=0.33 sys=0.00, real=0.06secs]2015-07-05T18:04:10.516+0800: [GC (Last ditch collection) [PSYoungGen: 0K->0K(88064K)] 23672K->23672K(275456K), 0.0021137 secs] [Times: user=0.00 sys=0.00, real=0.00secs]2015-07-05T18:04:10.518+0800: [Full GC (Last ditch collection) [PSYoungGen: 0K->0K(88064K)] [ParOldGen: 23672K->23655K(274944K)] 23672K->23655K(363008K), [Metaspace: 24981K->24981K(102400K)], 0.1025192 secs] [Times: user=0.69 sys=0.00, real=0.10secs]

Exceptionin thread "main"java.lang.OutOfMemoryError: Metaspace

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:760)

at java.lang.ClassLoader.defineClass(ClassLoader.java:642)

at Metaspace.main(Metaspace.java:37)

当Metaspace的空间增长到100M的时候,还需要继续增长,但是由于之前设置了Metaspace的最大值为100M,因此抛出了上面的异常

-XX:MinMetaspaceFreeRatio的使用

添加JVM参数,-XX:MinMetaspaceFreeRatio=65(注意此时-XX:MaxMetaspaceFreeRatio为70,min需要小于max,所以设置为), 这时的JVM参数变为

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:-UseCompressedClassPointers -XX:MetaspaceSize=50M -XX:MaxMetaspaceSize=100m -XX:MinMetaspaceFreeRatio=65

运行后的日志为,

2015-07-05T18:32:06.476+0800: [GC (Allocation Failure) [PSYoungGen: 33280K->5100K(38400K)] 33280K->7595K(125952K), 0.0093795 secs] [Times: user=0.00 sys=0.00, real=0.01secs]2015-07-05T18:32:06.555+0800: [GC (Metadata GC Threshold) [PSYoungGen: 24677K->5102K(71680K)] 27172K->11893K(159232K), 0.0077681 secs] [Times: user=0.00 sys=0.00, real=0.01secs]2015-07-05T18:32:06.563+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 5102K->0K(71680K)] [ParOldGen: 6790K->11703K(71680K)] 11893K->11703K(143360K), [Metaspace: 13581K->13581K(51200K)], 0.0424761 secs] [Times: user=0.16 sys=0.02, real=0.04secs]2015-07-05T18:32:06.826+0800: [GC (Metadata GC Threshold) [PSYoungGen: 55855K->5115K(71680K)] 67559K->23867K(143360K), 0.0121986 secs] [Times: user=0.06 sys=0.00, real=0.01secs]2015-07-05T18:32:06.838+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 5115K->0K(71680K)] [ParOldGen: 18751K->23672K(128000K)] 23867K->23672K(199680K), [Metaspace: 24981K->24981K(102400K)], 0.0786608 secs] [Times: user=0.31 sys=0.00, real=0.08secs]2015-07-05T18:32:06.917+0800: [GC (Last ditch collection) [PSYoungGen: 0K->0K(81920K)] 23672K->23672K(209920K), 0.0018780 secs] [Times: user=0.00 sys=0.00, real=0.00secs]2015-07-05T18:32:06.919+0800: [Full GC (Last ditch collection) [PSYoungGen: 0K->0K(81920K)] [ParOldGen: 23672K->23655K(179200K)] 23672K->23655K(261120K), [Metaspace: 24981K->24981K(102400K)], 0.0771198 secs] [Times: user=0.34 sys=0.00, real=0.08secs]

Exceptionin thread "main"java.lang.OutOfMemoryError: Metaspace

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:760)

at java.lang.ClassLoader.defineClass(ClassLoader.java:642)

at Metaspace.main(Metaspace.java:37)

似乎与之前没什么区别,但是仔细可以发现相比于不设置该参数少了一次FullGC。

如果将该参数设置的很小,比如10,则大约可以经历7次FullGC。

后面会讨论这个区别。

-XX:MinMetaspaceExpansion

去掉之前设置的-XX:MinMetaspaceFreeRatio,同时设置-XX:MinMetaspaceExpansion=100M,修改-XX:MaxMetaspaceSize为300M,此时的JVM参数为,

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:-UseCompressedClassPointers -XX:MetaspaceSize=50M -XX:MaxMetaspaceSize=300M -XX:MinMetaspaceExpansion=100M

运行后的日志为,

2015-07-05T18:53:25.466+0800: [GC (Allocation Failure) [PSYoungGen: 33280K->5100K(38400K)] 33280K->7607K(125952K), 0.0067215 secs] [Times: user=0.00 sys=0.00, real=0.01secs]2015-07-05T18:53:25.553+0800: [GC (Metadata GC Threshold) [PSYoungGen: 24676K->5102K(71680K)] 27183K->11881K(159232K), 0.0080541 secs] [Times: user=0.00 sys=0.00, real=0.01secs]2015-07-05T18:53:25.561+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 5102K->0K(71680K)] [ParOldGen: 6778K->11771K(73216K)] 11881K->11771K(144896K), [Metaspace: 13580K->13580K(51200K)], 0.0469926 secs] [Times: user=0.14 sys=0.00, real=0.05secs]2015-07-05T18:53:25.875+0800: [GC (Allocation Failure) [PSYoungGen: 66560K->5115K(71680K)] 78331K->26463K(144896K), 0.0146596 secs] [Times: user=0.06 sys=0.00, real=0.02secs]2015-07-05T18:53:26.110+0800: [GC (Metadata GC Threshold) [PSYoungGen: 48338K->5113K(91648K)] 69686K->35925K(164864K), 0.0151956 secs] [Times: user=0.05 sys=0.01, real=0.02secs]2015-07-05T18:53:26.125+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 5113K->0K(91648K)] [ParOldGen: 30811K->35633K(147456K)] 35925K->35633K(239104K), [Metaspace: 36381K->36381K(153600K)], 0.1574835 secs] [Times: user=0.66 sys=0.00, real=0.16secs]2015-07-05T18:53:26.818+0800: [GC (Allocation Failure) [PSYoungGen: 86528K->5109K(91648K)] 122161K->54855K(239104K), 0.0200557 secs] [Times: user=0.06 sys=0.00, real=0.02secs]2015-07-05T18:53:27.015+0800: [GC (Metadata GC Threshold) [PSYoungGen: 29014K->10133K(127488K)] 78760K->59879K(274944K), 0.0116375 secs] [Times: user=0.05 sys=0.02, real=0.01secs]2015-07-05T18:53:27.027+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 10133K->0K(127488K)] [ParOldGen: 49745K->59524K(221696K)] 59879K->59524K(349184K), [Metaspace: 59182K->59182K(256000K)], 0.2163024 secs] [Times: user=1.05 sys=0.00, real=0.22secs]2015-07-05T18:53:27.691+0800: [GC (Metadata GC Threshold) [PSYoungGen: 56721K->12448K(127488K)] 116245K->71972K(349184K), 0.0139748 secs] [Times: user=0.00 sys=0.00, real=0.01secs]2015-07-05T18:53:27.705+0800: [Full GC (Metadata GC Threshold) [PSYoungGen: 12448K->0K(127488K)] [ParOldGen: 59524K->71563K(306176K)] 71972K->71563K(433664K), [Metaspace: 70582K->70582K(307200K)], 0.1479683 secs] [Times: user=0.55 sys=0.00, real=0.15secs]2015-07-05T18:53:27.853+0800: [GC (Last ditch collection) [PSYoungGen: 0K->0K(144384K)] 71563K->71563K(450560K), 0.0045973 secs] [Times: user=0.00 sys=0.00, real=0.00secs]2015-07-05T18:53:27.857+0800: [Full GC (Last ditch collection) [PSYoungGen: 0K->0K(144384K)] [ParOldGen: 71563K->71546K(386048K)] 71563K->71546K(530432K), [Metaspace: 70582K->70582K(307200K)], 0.2734107 secs] [Times: user=1.65 sys=0.00, real=0.27secs]

Exceptionin thread "main"java.lang.OutOfMemoryError: Metaspace

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:760)

at java.lang.ClassLoader.defineClass(ClassLoader.java:642)

at Metaspace.main(Metaspace.java:37)

可以看出每次Metaspace空间的增长都在100MB左右,经历了3次的FullGC之后空间就达到了设置的上限300MB。

-XX:MinMetaspaceFreeRatio和-XX:MinMetaspaceExpansion

为了说明这二者有什么影响设置如下参数,

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:-UseCompressedClassPointers -XX:MetaspaceSize=50M -XX:MaxMetaspaceSize=500m -XX:MinMetaspaceExpansion=50M -XX:MaxMetaspaceExpansion=50M -XX:MinMetaspaceFreeRatio=5

之后修改MinMetaspaceFreeRatio的为20,35,50,65分别可以得到如下的GC数据

5

2015-07-05T20:47:47.444+0800: ... [Metaspace: 13580K->13580K(51200K)]...2015-07-05T20:47:47.741+0800: ... [Metaspace: 24981K->24981K(102400K)]...2015-07-05T20:47:48.150+0800: ... [Metaspace: 36381K->36381K(153600K)]...2015-07-05T20:47:48.584+0800: ... [Metaspace: 47781K->47781K(204800K)]...2015-07-05T20:47:49.124+0800: ... [Metaspace: 59182K->59182K(256000K)]...2015-07-05T20:47:49.717+0800: ... [Metaspace: 70582K->70582K(307200K)]...2015-07-05T20:47:50.462+0800: ... [Metaspace: 81982K->81982K(358400K)]...2015-07-05T20:47:51.278+0800: ... [Metaspace: 93382K->93382K(409600K)]...2015-07-05T20:47:52.272+0800: ... [Metaspace: 104782K->104782K(460800K)]...2015-07-05T20:47:53.418+0800: ... [Metaspace: 116182K->116182K(512000K)]...20

2015-07-05T20:50:16.123+0800: ... [Metaspace: 13580K->13580K(51200K)]...2015-07-05T20:50:16.404+0800: ... [Metaspace: 24981K->24981K(102400K)]...2015-07-05T20:50:16.754+0800: ... [Metaspace: 36381K->36381K(153600K)]...2015-07-05T20:50:17.234+0800: ... [Metaspace: 47781K->47781K(204800K)]...2015-07-05T20:50:17.758+0800: ... [Metaspace: 59182K->59182K(256000K)]...2015-07-05T20:50:18.499+0800: ... [Metaspace: 73432K->73432K(321536K)]...2015-07-05T20:50:19.591+0800: ... [Metaspace: 91244K->91244K(401408K)]...2015-07-05T20:50:21.326+0800: ... [Metaspace: 113510K->113510K(501760K)]...2015-07-05T20:50:21.868+0800: ... [Metaspace: 116182K->116182K(512000K)]...35

2015-07-05T20:56:02.338+0800: ... [Metaspace: 13581K->13581K(51200K)]...2015-07-05T20:56:02.619+0800: ... [Metaspace: 24981K->24981K(102400K)]...2015-07-05T20:56:03.010+0800: ... [Metaspace: 37258K->37258K(157696K)]...2015-07-05T20:56:03.733+0800: ... [Metaspace: 56146K->56146K(243712K)]...2015-07-05T20:56:05.233+0800: ... [Metaspace: 85206K->85206K(374784K)]...2015-07-05T20:56:07.548+0800: ... [Metaspace: 116182K->116182K(512000K)]...50

2015-07-05T20:59:08.866+0800: ... [Metaspace: 13580K->13580K(51200K)]...2015-07-05T20:59:09.153+0800: ... [Metaspace: 24981K->24981K(102400K)]...2015-07-05T20:59:09.863+0800: ... [Metaspace: 47781K->47781K(204800K)]...2015-07-05T20:59:12.178+0800: ... [Metaspace: 93382K->93382K(409600K)]...2015-07-05T20:59:14.031+0800: ... [Metaspace: 116182K->116182K(512000K)]...65

2015-07-05T21:01:03.353+0800: ... [Metaspace: 13581K->13581K(51200K)]...2015-07-05T21:01:03.888+0800: ... [Metaspace: 34753K->34753K(147456K)]...2015-07-05T21:01:06.648+0800: ... [Metaspace: 95245K->95245K(419840K)]...2015-07-05T21:01:08.547+0800: ... [Metaspace: 116182K->116182K(512000K)]...

从上面的数据可以看出

- 随着-XX:MinMetaspaceFreeRatio的不断增加,在到达设定的Max之前所经历的GC次数也就越少

-

随着-XX:MinMetaspaceFreeRatio的不断增加,平均下来每一次GC后对应的MetaSpaceSize相对于之前的增长幅度都会增加。比如在-XX:MinMetaspaceFreeRatio为5的时候,每次增长还基本上维持在设置的增长最小值(-XX:MinMetaspaceExpansion)50MB,而增长到65的时候,每次增长都在200MB以上。这似乎可以说明-XX:MinMetaspaceFreeRatio越大,JVM越认为需要快速的增长MetaSpaceSize以防止频繁的进行的进行GC

- -XX:MinMetaspaceFreeRatio设定的过小,会影响内存增长,导致比较频繁的GC。而过大怎会导致内存单次增长过多,造成不必要的浪费。默认的40是一个比较好的选择。

java8 metaspacesize_Metaspace 之三--jdk8 Metaspace 调优相关推荐

  1. 八张图彻底了解JDK8 GC调优秘籍-附PDF下载

    文章目录 简介 分代垃圾回收器的内存结构 JDK8中可用的GC 打印GC信息 内存调整参数 Thread配置 通用GC参数 CMS GC G1参数 总结 简介 JVM的参数有很多很多,根据我的统计JD ...

  2. 转 jdk8 jvm调优参数配置

    转载 jdk8 jvm调优参数配置_feiying00544的博客-CSDN博客_jdk8 jvm参数 1.由于jdk8开始,没有了永久区的概念,所以在jvm参数配置上不再需要 -XX:PermSiz ...

  3. 八张图彻底了解JDK8 GC调优秘籍!

    简介 JVM的参数有很多很多,根据我的统计JDK8中JVM的参数总共有1853个,正式的参数也有680个. 这么多参数带给我们的是对JVM的细粒度的控制,但是并不是所有的参数都需要我们自己去调节的,我 ...

  4. JAVA8 Metaspace内容_JDK8 metaspace调优

    从JDK8开始,永久代(PermGen)的概念被废弃掉了,取而代之的是一个称为Metaspace的存储空间.Metaspace使用的是本地内存,而不是堆内存,也就是说在默认情况下Metaspace的大 ...

  5. Java性能优化,操作系统内核性能调优,JYM优化,Tomcat调优

    文章目录 Java性能优化 尽量在合适的场合使用单例 尽量避免随意使用静态变量 尽量避免过多过常地创建Java对象 尽量使用final修饰符 尽量使用局部变量 尽量处理好包装类型和基本类型两者的使用场 ...

  6. java8 垃圾收集_面试官:怎么做JDK8的垃圾收集器的调优(面试常问)

    看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题.擦了擦额头上汗,我稍微调整了一下紧张的情绪,对面试官说: 在jdk8中有serial收集器.parallel收集器.cms收集器. ...

  7. java8 默认垃圾收集,面试官:怎么做JDK8的垃圾收集器的调优(面试常问)

    看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题.擦了擦额头上汗,我稍微调整了一下紧张的情绪,对面试官说: 在JDK8中有Serial收集器.Parallel收集器.CMS收集器. ...

  8. 面试官:怎么做JDK8的内存调优?

    面试官:怎么做JDK8的内存调优? 看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题.擦了擦额头上汗

  9. java8 虚拟机调优_Java虚拟机调优(八)-典型配置举例2

    背景: java虚拟机的东西,一直想分享下,弄了半天,太过理论了,也写不出太多特别的东西,看已经有朋友分享的很好了,还整理成了一个系统,就转载下,希望对朋友们有用,欢迎关注老王公众号[软件老王],关注 ...

最新文章

  1. 【spring】第二个springmvc helloworld 以及 spring模糊路径
  2. jQuery选择器总结
  3. make: Nothing to be done for `everything'.的原因
  4. HDFS namenode 高可用(HA)搭建指南 QJM方式 ——本质是多个namenode选举master,用paxos实现一致性...
  5. redis安装全过程
  6. 三十年TCP与七年QUIC 谁才是未来?
  7. mac电脑快捷键(持续更新)
  8. 成为一名成功的程序员要做到以下10点?网友:是真的吗?
  9. 超实用!18 个开箱即用的 Shell 脚本,拿好了~
  10. “敏捷项目管理就是胡闹!”
  11. mysql 模糊查询之特殊字符下划线 _
  12. 【PAT乙】1003 我要通过! (20分) 字符串条件判定
  13. 用 JavaScript 实现内存位翻转漏洞
  14. centos查询 硬盘序列号查询_关于使用java执行shell脚本获取centos的硬盘序列号和mac地址...
  15. linux 如何看图软件,深度看图(linux看图软件) v1.2 官方最新版
  16. pinctrl学习笔记---描述/获得引脚
  17. 0203逻辑卷管理、RAID磁盘阵列、VD0、管理运行级别
  18. 红米10xpro手机图纸
  19. 2020中兴开发岗笔试题
  20. LTE网络PUCCH功控计算

热门文章

  1. [激活函数] 非线性原因分析、Sigmoid、TanH、ReLU和ELU
  2. CF981G Magic multisets
  3. 2015年语音识别文献阅读报告
  4. “互联网+”定义及相关概念解析
  5. 贴图、纹理、材质、着色器
  6. vue修改滚动条样式
  7. Unity 技术之对集成显卡进行优化
  8. 梅科尔工作室——深度学习第五课
  9. 专为实习生开发的一款程序:实习宙
  10. 【正点原子FPGA连载】第二十五章HDMI方块移动实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1