设置MetaspaceSize的指南-java 8
64位服务器的MetaspaceSize的默认值是多少?我在官方文件中找不到它 我观察到,在服务器JVM进程中,GC频率有时会变得很高并不断增长。如果我重新启动服务几次,它就会恢复稳定。我认为这是由于JRE升级 JVM堆最大大小设置为6GB,但当出现此问题时,我们只看到使用了3GB堆。元空间增长很小,几乎总是满的。我尝试将元空间增加到1GB,这提高了吞吐量 我认为正在发生的是,默认情况下,Metaspace被设置为一个非常低的值,因此GC起作用。每次GC发生时,高水位线持续增加(再次以非常低的量增加) 我想设置MetaspaceSize(不确定当前值是多少) Oracle文档表示,没有任何指导原则可以知道将MetaspaceSize设置为什么。但是有没有办法找出将其设置为正确的值 我从Oracle文档中得到的一个提示是:设置MetaspaceSize的指南-java 8,java,memory-leaks,java-8,out-of-memory,metaspace,Java,Memory Leaks,Java 8,Out Of Memory,Metaspace,64位服务器的MetaspaceSize的默认值是多少?我在官方文件中找不到它 我观察到,在服务器JVM进程中,GC频率有时会变得很高并不断增长。如果我重新启动服务几次,它就会恢复稳定。我认为这是由于JRE升级 JVM堆最大大小设置为6GB,但当出现此问题时,我们只看到使用了3GB堆。元空间增长很小,几乎总是满的。我尝试将元空间增加到1GB,这提高了吞吐量 我认为正在发生的是,默认情况下,Metaspace被设置为一个非常低的值,因此GC起作用。每次GC发生时,高水位线持续增加(再次以非常低的量
如果类元数据可用的提交空间占类元数据总提交空间的百分比大于MaxMetaspaceFreeRatio,则高水位线将降低。如果小于MinMetaspaceFreeRatio,则高水位线将升高。
但仍然无法确定如何稳定地面军事系统。我有三个问题:
我认为最有趣的问题是#3,所以我先回答这个问题。我的方法是使用以下设置在打开gc日志记录的情况下运行我的应用程序24小时:
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCCause
-XX:+PrintTenuringDistribution
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCApplicationConcurrentTime
-Xloggc:gc.log
然后我做了这个:
grep Metaspace gc.log
看到“使用”价值迅速增长到8000万。。。所以我将MetaspaceSize设置为100M
-XX:MetaspaceSize=100M
瞧,由于元空间,没有更多的地面军事系统
@posal的评论似乎很好地回答了您关于如何确定实现的默认元空间设置的前两个问题。。。为了完整起见,我会将其包括在这里:
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version -XX:+UseG1GC | grep Metaspace
从技术上讲,@posal的评论没有告诉您任何64位服务器的默认元空间大小,但这是因为您的第一个问题有点误导,因为根据文档,这些默认值在每个实现中都有所不同
见:
具体地说,底部的部分说,“MetaspaceSize的默认大小取决于平台,范围从12 MB到大约20 MB”自Java 8以来,可以使用以下命令行选项控制两个最重要的metaspace设置:
-当最初为类元数据提交的空间达到此级别时,将引发垃圾回收;根据采集结果,可随后提高或降低液位-XX:MetaspaceSize=N
-设置元空间的最大大小-XX:MaxMetaspaceSize=N
- 类元数据在卸载相应的Java类时被解除分配。Java类作为垃圾收集的结果被卸载,垃圾收集可能被诱导卸载类并解除分配类元数据。当为类元数据提交的空间达到某个级别(高水位线)时,将引发垃圾回收。垃圾回收后,根据从类元数据释放的空间大小,可以提高或降低高水位线。将提高高水位线,以免过早引发另一次垃圾回收。高水位线最初设置为命令行选项
[…]默认的-XX的值:MetaspaceSize
大小取决于平台,范围从12 MB到大约20 MB。”-XX:MetaspaceSize
- “默认情况下,可用于类元数据的本机内存量是无限的。请使用选项
设置用于类元数据的本机内存量的上限。”-XX:MaxMetaspaceSize
... -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m ...
但是,在大型生产应用程序中,MaxMetaspaceSize
可能需要大得多,因为它需要包含应用程序中所有加载类的元数据,并且您可能希望为MetaspaceSize
指定更高的值,以避免早期垃圾收集
另请参见@Eugene的回答,了解如何根据经验确定元空间设置。
MetaspaceSize
是触发完整GC
时的值,不是初始空间,也不是最大空间
它的默认值为20MB
(至少在jdk-8
至jdk-13
上):
将产生:
size_t MetaspaceSize = 21807104 // 20MB
这意味着当Metaspace
达到20MB
时,将触发Full GC
,如果您可以避免,那就好了
考虑到元空间可能容纳的数据量(方法、注释等),在我看来20MB
是一个非常小的值。不幸的是,选择正确的值并不容易
您有两个选项,启用gc日志记录-Xlog:gc
,让应用程序运行一段时间,然后查找如下实例:
[Full GC (Metadata GC Threshold) ...]
并从中了解您需要设置什么以及如何设置
或从以下内容开始此过程:
java -XX:NativeMemoryTracking=detail
通过以下方式连接到PID
:
jcmd <YourJVMPID> VM.metaspace
java-XX:+UnlockDiagnosticVMOptions-XX:+PrintFlagsFinal-version-XX:+UseG1GC | grep Metaspace
“我认为默认情况下,Metaspace被设置为一个非常低的值,因此GC启动”-你为什么这么认为?你的解释没有暗示为什么首先要归咎于元空间和
jcmd <YourJVMPID> VM.metaspace
Virtual space:
Non-class space: 8.00 MB reserved, 4.25 MB ( 53%) committed
Class space: 1.00 GB reserved, 512.00 KB ( <1%) committed
Both: 1.01 GB reserved, 4.75 MB ( <1%) committed
java -XX:+PrintFlagsFinal -version | grep Metaspace