点击下方“JavaEdge”,选择“设为星标”
第一时间关注技术干货!
免责声明~ 任何文章不要过度深思! 万事万物都经不起审视,因为世上没有同样的成长环境,也没有同样的认知水平,更「没有适用于所有人的解决方案」; 不要急着评判文章列出的观点,只需代入其中,适度审视一番自己即可,能「跳脱出来从外人的角度看看现在的自己处在什么样的阶段」才不为俗人。 怎么想、怎么做,全在乎自己「不断实践中寻找适合自己的大道」
本文探讨Metaspace和元数据GC阈值(Metadata GC Threshold)及如何调整它们这些参数。
Metadata包含有关堆中对象的信息,包括类定义、方法表等相关信息。根据Java的版本,JVM将这些数据存储在永久代(Permanent Generation)或Metaspace。
JVM依靠这些信息来执行类加载、字节码验证和动态绑定等任务。
Java 8开始,JVM用一个叫做Metaspace的新内存区域替代了永久代(PermGen)来存储元数据。
Java中,当我们创建一个带有元数据的对象时,它会像其他对象一样占用内存空间。JVM需要这些元数据来执行各种任务。与普通对象不同,元数据在达到某阈值之前不会进行垃圾回收。
随着Java程序执行过程中动态加载的类越来越多,Metaspace会逐渐填满。
JVM为Metaspace内容大小设置了一个阈值,当某个分配不符合此阈值时,会触发一次元数据GC阈值的垃圾回收周期。
可用类似-XX:+PrintClassHistogram
和-XX:+PrintMetaspaceStatistics
的JVM标志来收集有关使用大量元数据内存的类的信息,并打印有关Metaspace的统计信息,如用于类元数据的空间量。
使用这些信息,可优化代码以改善Metaspace和垃圾回收周期的使用情况。此外,我们还可以调整与Metaspace相关的JVM参数。
下面是一些用于调整元数据和Metaspace的JVM参数。
-XX:MetaspaceSize=<size>
用于设置分配给类元数据的初始空间量(初始高水位线,以字节为单位),该空间量可能会导致垃圾回收以卸载类。这个数值是近似的,这意味着JVM也可以决定增加或减少Metaspace的大小。
较大的参数值可以确保垃圾回收发生的频率较低。此参数的默认值取决于平台,范围从12 MB到约20 MB。
如设为128 MB:
-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=<size>
设置Metaspace的最大大小,超过此大小后会抛出OutOfMemory错误。此标志限制了分配给类元数据的空间量,分配给此参数的值是近似的。
默认情况下,没有设置限制,这意味着Metaspace可能增长到可用本地内存的大小。
如置100 MB:
‑XX:MaxMetaSpaceSize=100m
-XX:+UseCompressedClassPointers
通过压缩对象引用来减少64位Java应用程序的内存占用。当此参数设置为true时,JVM将使用压缩指针来处理类元数据,这使得JVM可以使用32位寻址来处理类相关数据,而不是完整的64位指针。
在64位架构上,此优化尤其有价值,因为它减少了类元数据的内存使用,以及对象引用所需的内存,从而可能提高应用程序的整体性能。
压缩类指针将类空间分配与非类空间分配分开。因此,我们有两个全局Metaspace上下文:一个用于保存Klass结构的分配(压缩类空间),一个用于保存其他所有内容(非类Metaspace)。
最近JVM版本中,通常在运行64位Java应用程序时,默认启用此标志,因此我们通常不需要显式设置此标志。
-XX:+UseCompressedOops
标志启用或禁用在64位JVM中使用压缩指针处理Java对象。当参数设置为true时,JVM将使用压缩指针,这意味着对象引用将使用32位指针,而不是完整的64位指针。
使用压缩指针,只能寻址较小范围的内存。这迫使JVM使用较小的指针并节省内存。
本文中,我们探讨了元数据和Metaspace的概念。
我们探讨了触发元数据GC阈值的原因。我们还了解了元数据GC阈值以及用于调整Metaspace和优化垃圾回收周期的不同JVM参数。
下一讲,我们讨论Metaspace导致的一个 OOM 生产排查案例!
编程严选网:
http://www.javaedge.cn/
专注分享软件开发全生态相关技术文章
、视频教程
资源、热点资讯等,全站资源免费学习,快来看看吧~
欢迎长按图片加好友
,我会第一时间和你分享软件行业趋势
,面试资源
,学习方法
等等。