JVM堆内存分配优化

准备一个小案例,提供一个接口,每次调用都会生成1个1M的对象,然后方法返回,对象由垃圾收集器自动回收。

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GCController {

    @RequestMapping("/gcTest")
    public String gcTest() {
        byte[] bytes = new byte[1024 * 1024];
        return "success";
    }
}

测试意图:使用压测工具模拟并发请求这个接口,并通过调整堆内存分配,看看对吞吐量、请求等待时间等指标的影响。

压测工具:apache bench

服务器环境:linux虚拟机,2g内存,单核处理器。

使用默认参数启动服务,并查看默认堆内存分配情况

在这里插入图片描述

1、模拟10个并发请求10万次

ab -c 10 -n 100000 http://127.0.0.1:8080/gcTest

在这里插入图片描述
在这里插入图片描述

测试结果:

总耗时:38.675 seconds
吞吐量:2585.64 [#/sec]
用户平均请求等待事件:3.868 [ms]
服务器平均请求处理时间:0.387 [ms]

YGC:12566次,耗时:12.336秒,FGC:2次,耗时:0.052,总计耗时:12.387秒

2、模拟100个并发请求10万次

ab -c 100 -n 100000 http://127.0.0.1:8080/gcTest

在这里插入图片描述

在这里插入图片描述

测试结果:

总耗时:44.511 seconds
吞吐量:2246.62 [#/sec]
用户平均请求等待事件:44.511 [ms]
服务器平均请求处理时间:0.445 [ms]

YGC:7851次,耗时:16.673秒,FGC:3次,耗时:0.116,总计耗时:16.789秒

使用指定堆大小和老年代大小参数启动服务

-Xms1500m -Xmx1500m

在这里插入图片描述

1、模拟10个并发请求10万次

ab -c 10 -n 100000 http://127.0.0.1:8080/gcTest

在这里插入图片描述

在这里插入图片描述

测试结果:

总耗时:37.939 seconds
吞吐量:2635.84 [#/sec]
用户平均请求等待事件:3.794 [ms]
服务器平均请求处理时间:0.379 [ms]

YGC:261次,耗时:0.462秒,FGC:2次,耗时:0.154,总计耗时:0.616秒

2、模拟100个并发请求10万次

ab -c 100 -n 100000 http://127.0.0.1:8080/gcTest

在这里插入图片描述

在这里插入图片描述

测试结果:

总耗时:36.389 seconds
吞吐量:2748.05 [#/sec]
用户平均请求等待事件:36.389 [ms]
服务器平均请求处理时间:0.364 [ms]

YGC:260次,耗时:0.552秒,FGC:2次,耗时:0.155,总计耗时:0.707秒

使用指定堆大小、老年代、新生代大小参数启动服务

-Xms1500m -Xmx1500m -Xmn1000m

在这里插入图片描述

1、模拟10个并发请求10万次

ab -c 10 -n 100000 http://127.0.0.1:8080/gcTest

在这里插入图片描述

在这里插入图片描述

测试结果:

总耗时:36.166 seconds
吞吐量:2765.06 [#/sec]
用户平均请求等待事件:3.617 [ms]
服务器平均请求处理时间:0.362 [ms]

YGC:130次,耗时:0.254秒,FGC:2次,耗时:0.213,总计耗时:0.467秒

2、模拟100个并发请求10万次

ab -c 100 -n 100000 http://127.0.0.1:8080/gcTest

在这里插入图片描述

在这里插入图片描述

测试结果:

总耗时:34.479 seconds
吞吐量:2900.33 [#/sec]
用户平均请求等待事件:34.479 [ms]
服务器平均请求处理时间:0.345 [ms]

YGC:130次,耗时:0.479秒,FGC:2次,耗时:0.144,总计耗时:0.623秒。

最终测试结果

在这里插入图片描述

总结

本次测试模拟接口在高并发频、高频次调用时,频繁的创建对象、造成新生代空间不足,频繁的触发新生代垃圾回收。
比如秒杀接口的调用,线上注意合理分配新生代大小,默认新生代与老年代比例为1:2,一些特定的场景也可以适当调整占比,以减少新生代垃圾回收的次数,通过jstat观察垃圾回收的情况,当新生代回收次数特别多,老年代特别少,可以适当进行调整。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码拉松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值