jvm踩坑日记

本文记录了一次JVM调优过程,探讨了类指针压缩在64位操作系统中的作用和原理,以及如何通过调整JVM参数优化服务启动数量。通过分析,发现由于默认最大堆大小限制,服务器只能启动约20个服务。解决方案是手动指定适合的JVM参数,尤其是关于类指针压缩的配置,以支持更大内存配置并提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景:
负责的算法平台项目将上传的算法jar包打包成一个spingboot的可执行jar包,项目中用命令启动该服务,命令如下:

String filePath = this.moduleFileRootPath + "/" + moduleId + "/" + version + "/algrithm-module-"
        + moduleId + "-" + version + ".jar";
nohup java -jar " + filePath + " --server.port=" + port + " --putParamsJson="
              + moduleConfigsJson

发现当120G内存的服务器启动20个左右的服务的时候,就不能在启动服务了,这远远低于我们的预期,我用jstat -gcutil 进程号 命令,结果如下:
在这里插入图片描述
S0、S1 代表两个Survivor区;

E 代表 Eden 区;

O(Old)代表老年代;

M(MateSpace)代表元空间(jdk1.8之后修改为mateSpace,之前是永久代Permanent);
CCS (Young GC)代表 类指针压缩空间使用率,下面会介绍类指针压缩;

YGC(Young GC)代表Minor GC;

YGCT代表Minor GC耗时;

FGC(Full GC)代表Full GC耗时;

GCT代表Minor & Full GC共计耗时。
当我看到元空间和类指针压缩空间使用率都百分之90多,我错误了将问题的方向指向这里,我以为是占用率过多导致的,但是FGC的次数是2,FGC时间也不是很频繁,看了博客说元空间内存的释放是要触发FGC的,所以问题并不在这。。。
然后执行jmap命令查看生产服务的堆的信息, jmap -heap 进程号,不看不知道一看吓一跳,最大堆竟然32g
在这里插入图片描述
突然想到,我们生成的算法服务没有指定jvm的参数信息,都是按照默认的生成的,去oracle官网找了一下官方文档,翻译成中文的意思如下:
在这里插入图片描述
符合预期,生成的服务的最大堆果然是官网上说的32g,这也就难怪服务器只能生成20个左右的服务了,所以把代码的修改为

 "nohup java -Xms1024m -Xmx1024m -jar " + filePath + " --server.port=" + port + " --putParamsJson="
              + moduleConfigsJson

指定一下jvm合适的默认参数就行了

**

类指针压缩

**

什么是java对象的指针压缩?
1.jdk1.6 update14开始,在64bit操作系统中,JVM支持指针压缩
2.jvm配置参数:UseCompressedOops,compressed–压缩、oop–对象指针
3.启用指针压缩:-XX:+UseCompressedOops,禁止指针压缩:-XX:-UseCompressedOops

为什么要进行指针压缩?
1.在64位平台的HotSpot中使用32位指针,内存使用会多出1.5倍左右,使用较大指针在主内存和缓存之间移动数据,占用较大宽带,同时GC也会承受较大压力
2.为了减少64位平台下内存的消耗,启用指针压缩功能
3.在jvm中,32位地址表示4G个对象的指针,在4G-32G堆内存范围内,可以通过编码、解码方式进行优化,使得jvm可以支持更大的内存配置
4.堆内存小于4G时,不需要启用指针压缩,jvm会直接去除高32位地址,即使用低虚拟地址空间
5.堆内存大于32G时,压缩指针会失效,会强制使用64位(即8字节)来对java对象寻址,这就会出现1的问题,所以堆内存不要大于32G为好

指针压缩的原理是什么?
1.解释器解释字节码,植入压缩指令,进行编码、解码
2.需要操作系统底层支持:GC堆从虚拟地址0开始分配

哪些信息会被压缩?
1.对象的全局静态变量(即类属性)
2.对象头信息:64位平台下,原生对象头大小为16字节,压缩后为12字节
3.对象的引用类型:64位平台下,引用类型本身大小为8字节,压缩后为4字节
4.对象数组类型:64位平台下,数组类型本身大小为24字节,压缩后16字节

哪些信息不会被压缩?
1.指向非Heap的对象指针
2.局部变量、传参、返回值、NULL指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值