简介

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

更多Meatspace内容见《Metaspace 之一:Metaspace整体介绍(永久代被替换原因、元空间特点、元空间内存查看分析方法)

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

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

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

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

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

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

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

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

在《四、jdk工具之jstat命令2(Java Virtual Machine Statistics Monitoring Tool)详解》文章中,介绍了jstat -gcutil的多个参数的含义。

一个误解

使用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的初始化阈值,也是最小的阈值。这里有几个要点需要明确:

  1. 如果没有配置-XX:MetaspaceSize,那么触发FGC的阈值是21807104(约20.8m),可以通过jinfo -flag MetaspaceSize pid得到这个值;jps -v也可以查看jvm的参数设置情况。
  2. 如果配置了-XX:MetaspaceSize,那么触发FGC的阈值就是配置的值;
  3. Metaspace由于使用不断扩容到-XX:MetaspaceSize参数指定的量,就会发生FGC;且之后每次Metaspace扩容都可能会发生FGC(至于什么时候会,比较复杂,跟几个参数有关);
  4. 如果Old区配置CMS垃圾回收,那么扩容引起的FGC也会使用CMS算法进行回收;
  5. 如果MaxMetaspaceSize设置太小,可能会导致频繁FullGC,甚至OOM;

建议

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

测试代码

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

import java.util.ArrayList;
import java.util.List; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; /*
* 继承ClassLoader是为了方便调用defineClass方法,因为该方法的定义为protected
* */
public class Metaspace extends ClassLoader {
public static void main(String[] args) {
// 类持有
List<Class<?>> classes = new ArrayList<Class<?>>();
// 循环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);
// 定义构造函数<init>方法
MethodVisitor mw = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
"()V", null, null);
// 第一个指令为加载this
mw.visitVarInsn(Opcodes.ALOAD, 0);
// 第二个指令为调用父类Object的构造函数
mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object",
"<init>", "()V", false);
// 第三条指令为return
mw.visitInsn(Opcodes.RETURN);
mw.visitMaxs(1, 1);
mw.visitEnd(); Metaspace test = new Metaspace();
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

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

--05T16::53.708+: [GC (Metadata GC Threshold) [PSYoungGen: 13978K->3229K(38400K)] 13978K->3237K(125952K), 0.0043062 secs] [Times: user=0.06 sys=0.02, real=0.00 secs]
--05T16::53.712+: [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 class space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:)
at java.lang.ClassLoader.defineClass(ClassLoader.java:)
at Metaspace.main(Metaspace.java:)

根据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

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

--05T17::31.030+: [GC (Metadata GC Threshold) [PSYoungGen: 21301K->4984K(38400K)] 21301K->4992K(125952K), 0.0041727 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
--05T17::31.034+: [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

运行后出现的日志为,

--05T17::20.430+: [GC (Allocation Failure) [PSYoungGen: 33280K->5100K(38400K)] 33280K->7635K(125952K), 0.0076185 secs] [Times: user=0.03 sys=0.03, real=0.01 secs]
--05T17::20.511+: [GC (Metadata GC Threshold) [PSYoungGen: 24676K->5102K(71680K)] 27211K->11885K(159232K), 0.0085707 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
--05T17::20.519+: [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

运行后出现的日志为,

--05T18::10.000+: [GC (Allocation Failure) [PSYoungGen: 33280K->5116K(38400K)] 33280K->7627K(125952K), 0.0069565 secs] [Times: user=0.08 sys=0.00, real=0.01 secs]
--05T18::10.086+: [GC (Metadata GC Threshold) [PSYoungGen: 24689K->5102K(71680K)] 27199K->11917K(159232K), 0.0092239 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
--05T18::10.095+: [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.06 secs]
--05T18::10.297+: [GC (Metadata GC Threshold) [PSYoungGen: 37664K->5106K(71680K)] 49367K->19785K(145920K), 0.0066032 secs] [Times: user=0.11 sys=0.00, real=0.01 secs]
--05T18::10.304+: [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.08 secs]
--05T18::10.454+: [GC (Metadata GC Threshold) [PSYoungGen: 19414K->4219K(82432K)] 39079K->23884K(211968K), 0.0048493 secs] [Times: user=0.11 sys=0.00, real=0.01 secs]
--05T18::10.459+: [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.06 secs]
--05T18::10.516+: [GC (Last ditch collection) [PSYoungGen: 0K->0K(88064K)] 23672K->23672K(275456K), 0.0021137 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
--05T18::10.518+: [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.10 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:)
at java.lang.ClassLoader.defineClass(ClassLoader.java:)
at Metaspace.main(Metaspace.java:)
当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

运行后的日志为,

--05T18::06.476+: [GC (Allocation Failure) [PSYoungGen: 33280K->5100K(38400K)] 33280K->7595K(125952K), 0.0093795 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
--05T18::06.555+: [GC (Metadata GC Threshold) [PSYoungGen: 24677K->5102K(71680K)] 27172K->11893K(159232K), 0.0077681 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
--05T18::06.563+: [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.04 secs]
--05T18::06.826+: [GC (Metadata GC Threshold) [PSYoungGen: 55855K->5115K(71680K)] 67559K->23867K(143360K), 0.0121986 secs] [Times: user=0.06 sys=0.00, real=0.01 secs]
--05T18::06.838+: [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.08 secs]
--05T18::06.917+: [GC (Last ditch collection) [PSYoungGen: 0K->0K(81920K)] 23672K->23672K(209920K), 0.0018780 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
--05T18::06.919+: [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.08 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:)
at java.lang.ClassLoader.defineClass(ClassLoader.java:)
at Metaspace.main(Metaspace.java:)

似乎与之前没什么区别,但是仔细可以发现相比于不设置该参数少了一次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

运行后的日志为,

--05T18::25.466+: [GC (Allocation Failure) [PSYoungGen: 33280K->5100K(38400K)] 33280K->7607K(125952K), 0.0067215 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
--05T18::25.553+: [GC (Metadata GC Threshold) [PSYoungGen: 24676K->5102K(71680K)] 27183K->11881K(159232K), 0.0080541 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
--05T18::25.561+: [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.05 secs]
--05T18::25.875+: [GC (Allocation Failure) [PSYoungGen: 66560K->5115K(71680K)] 78331K->26463K(144896K), 0.0146596 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]
--05T18::26.110+: [GC (Metadata GC Threshold) [PSYoungGen: 48338K->5113K(91648K)] 69686K->35925K(164864K), 0.0151956 secs] [Times: user=0.05 sys=0.01, real=0.02 secs]
--05T18::26.125+: [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.16 secs]
--05T18::26.818+: [GC (Allocation Failure) [PSYoungGen: 86528K->5109K(91648K)] 122161K->54855K(239104K), 0.0200557 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]
--05T18::27.015+: [GC (Metadata GC Threshold) [PSYoungGen: 29014K->10133K(127488K)] 78760K->59879K(274944K), 0.0116375 secs] [Times: user=0.05 sys=0.02, real=0.01 secs]
--05T18::27.027+: [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.22 secs]
--05T18::27.691+: [GC (Metadata GC Threshold) [PSYoungGen: 56721K->12448K(127488K)] 116245K->71972K(349184K), 0.0139748 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
--05T18::27.705+: [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.15 secs]
--05T18::27.853+: [GC (Last ditch collection) [PSYoungGen: 0K->0K(144384K)] 71563K->71563K(450560K), 0.0045973 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
--05T18::27.857+: [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.27 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:)
at java.lang.ClassLoader.defineClass(ClassLoader.java:)
at Metaspace.main(Metaspace.java:)

可以看出每次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数据

--05T20::47.444+: ... [Metaspace: 13580K->13580K(51200K)]...
--05T20::47.741+: ... [Metaspace: 24981K->24981K(102400K)]...
--05T20::48.150+: ... [Metaspace: 36381K->36381K(153600K)]...
--05T20::48.584+: ... [Metaspace: 47781K->47781K(204800K)]...
--05T20::49.124+: ... [Metaspace: 59182K->59182K(256000K)]...
--05T20::49.717+: ... [Metaspace: 70582K->70582K(307200K)]...
--05T20::50.462+: ... [Metaspace: 81982K->81982K(358400K)]...
--05T20::51.278+: ... [Metaspace: 93382K->93382K(409600K)]...
--05T20::52.272+: ... [Metaspace: 104782K->104782K(460800K)]...
--05T20::53.418+: ... [Metaspace: 116182K->116182K(512000K)]... --05T20::16.123+: ... [Metaspace: 13580K->13580K(51200K)]...
--05T20::16.404+: ... [Metaspace: 24981K->24981K(102400K)]...
--05T20::16.754+: ... [Metaspace: 36381K->36381K(153600K)]...
--05T20::17.234+: ... [Metaspace: 47781K->47781K(204800K)]...
--05T20::17.758+: ... [Metaspace: 59182K->59182K(256000K)]...
--05T20::18.499+: ... [Metaspace: 73432K->73432K(321536K)]...
--05T20::19.591+: ... [Metaspace: 91244K->91244K(401408K)]...
--05T20::21.326+: ... [Metaspace: 113510K->113510K(501760K)]...
--05T20::21.868+: ... [Metaspace: 116182K->116182K(512000K)]... --05T20::02.338+: ... [Metaspace: 13581K->13581K(51200K)]...
--05T20::02.619+: ... [Metaspace: 24981K->24981K(102400K)]...
--05T20::03.010+: ... [Metaspace: 37258K->37258K(157696K)]...
--05T20::03.733+: ... [Metaspace: 56146K->56146K(243712K)]...
--05T20::05.233+: ... [Metaspace: 85206K->85206K(374784K)]...
--05T20::07.548+: ... [Metaspace: 116182K->116182K(512000K)]... --05T20::08.866+: ... [Metaspace: 13580K->13580K(51200K)]...
--05T20::09.153+: ... [Metaspace: 24981K->24981K(102400K)]...
--05T20::09.863+: ... [Metaspace: 47781K->47781K(204800K)]...
--05T20::12.178+: ... [Metaspace: 93382K->93382K(409600K)]...
--05T20::14.031+: ... [Metaspace: 116182K->116182K(512000K)]... --05T21::03.353+: ... [Metaspace: 13581K->13581K(51200K)]...
--05T21::03.888+: ... [Metaspace: 34753K->34753K(147456K)]...
--05T21::06.648+: ... [Metaspace: 95245K->95245K(419840K)]...
--05T21::08.547+: ... [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是一个比较好的选择。

jdk8 Metaspace 调优的更多相关文章

  1. [转帖]jdk8 Metaspace 调优

    jdk8 Metaspace 调优 https://blog.csdn.net/bolg_hero/article/details/78189621 转帖 简介 从JDK8开始,永久代(PermGen ...

  2. JDK8 metaspace调优

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

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

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

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

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

  5. 记录一次Metaspace扩容引发FGC的调优总结

    开始之前 在开始之前先记录一个我碰到的jvm调优的坑.那就是… 为啥我配置到idea64exe.vmoptions中的参数没有生效??? 由于之前一直是在mac上开发,本地开发时当需要优化jvm参数的 ...

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

    面试官:怎么做JDK8的内存调优? 看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题.擦了擦额头上汗,我稍微调整了一下紧张的情绪,对面试官说: 在内存调优之前,需要先了解JDK8的 ...

  7. 面试官:怎么做JDK8的垃圾收集器的调优?

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

  8. 一篇年薪60万的JVM性能调优文章

    JVM 调优概述 性能定义 吞吐量 - 指不考虑 GC 引起的停顿时间或内存消耗,垃圾收集器能支撑应用达到的最高性能指标. 延迟 - 其度量标准是缩短由于垃圾啊收集引起的停顿时间或者完全消除因垃圾收集 ...

  9. 阿里面试100%问到,JVM性能调优篇

    JVM 调优概述 性能定义 吞吐量 - 指不考虑 GC 引起的停顿时间或内存消耗,垃圾收集器能支撑应用达到的最高性能指标. 延迟 - 其度量标准是缩短由于垃圾啊收集引起的停顿时间或者完全消除因垃圾收集 ...

随机推荐

  1. hello2源代码解析

    String username = request.getParameter("username");/**以 String 形式返回请求参数"username" ...

  2. Wincc用户登录VBS脚本

    在Wincc中为防止未知用户的误操作,在操作性按钮以及图符等设备操作面板,在组流程图时,需设置用户权限,只有符合权限的用户才可以进行操作.所以在流程图界面需设置系统用户登录界面.登录操作可以选择按钮或 ...

  3. 使用MongoDB数据库(2)(三十六)

    快速开始使用Spring-data-mongodb 若MongoDB的安装配置采用默认端口,那么在自动配置的情况下,我们不需要做任何参数配置,就能马上连接上本地的MongoDB.下面直接使用sprin ...

  4. vs 设置自动缩进tab转换成空格

    工具   选项   文本编辑器    如下图  选中插入空格 使用技巧: 按Ctrl+K+F组合键,可以自动进行代码对齐.

  5. js实现滚动条来动态加载数据

    主要angular2+es6 data:Array<any> //展示的数据 allData:Array<any> //全部的数据 size:number = 10 //每次动 ...

  6. Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)

    项目地址https://github.com/979451341/FFmpegOpenslES 这次说的是FFmpeg解码mp3,数据给OpenSL ES播放,并且能够暂停. 1.创建引擎 slCre ...

  7. keepalived高可用集群。

    keepalived故障切换转移原理1vrrp协议:(vritual router redundancy protocol)虚拟路由冗余协议,2故障转移.keepalived三大功能1实现物理高可用, ...

  8. python全栈开发笔记----基本数据类型---列表方法

    #list 类中提供的方法 #参数 1.def append(self, *args, **kwargs)原来值最后追加#对象..方法(..) #li对象调用append方法 li = [11,22, ...

  9. react native 环境报错

    按照react native中文网的文档安装 1.brew 管理软件 2.node 在终端启动工程后就报下面这个错误 这个错误是在RN在第一次配置环境启动一个工程的时候 ,在这过程中下载的缓存文件不完 ...

  10. [转] C++ 和 python之间的互相调用

    转载自:https://www.cnblogs.com/apexchu/p/5015961.html 一.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库比较简单,不 ...