是时候讲讲JVM调优了
这节课中我会教你如何计算对象的大小,然后会讲到影响对象大小的一个底层技术:指针压缩及其实现细节,最后咱们通过实战来深刻理解JVM调优。
oop模型
第一个课给大家讲了Klass模型,它是Java类的元信息在JVM中的存在形式。今天讲的oop模型是Java对象在JVM中的存在形式
对象的内存布局
第一张图是大家眼中的内存布局图,但是我在测试的过程中我发现还有另外一种情况,具体细节咱们课上谈
计算对象大小
具体细节见课堂上操作实战
用jol-core包或者HSDB都可以看,区别是HSDB只能看基于普通类生成对象的大小,java中的数组因为是运行时生成的,故它的大小只有运行时才能知晓。
1、空对象(没有实例属性的对象)
public class CountEmptyObjectSize {
public static void main(String[] args) {
CountEmptyObjectSize obj = new CountEmptyObjectSize();
System.out.println(ClassLayout.parseInstance(obj).toPrintable());
}
}
2、普通对象
public class CountObjectSize {
int a = 10;
int b = 20;
public static void main(String[] args) {
CountObjectSize object = new CountObjectSize();
System.out.println(ClassLayout.parseInstance(object).toPrintable());
}
}
3、数组对象
public class CountSimpleObjectSize {
static int[] arr = {0, 1, 2};
public static void main(String[] args) {
CountSimpleObjectSize test1 = new CountSimpleObjectSize();
System.out.printf(ClassLayout.parseInstance(arr).toPrintable());
}
}
指针压缩
具体细节见课堂上操作实战
jdk6以后引入的技术,默认是开启的,可以调优:-XX:+/-UseCompressedOops
1、指针压缩的实现原理
2、开启指针压缩的情况下,一个oop表示的最大对空间是多少
3、如何扩容
4、为什么没这样做
5、扩容是修改OS底层源码还是JVM底层源码
JVM调优
1、为什么要调优
- 防止出现OOM
- 解决OOM
- 减少full gc出现的频率
2、到底调什么
- 在项目部署到线上之前,基于可能的并发量进行预估调优
- 在项目运行过程中,部署监控收集性能数据,平时分析日志进行调优
- 线上出现OOM,进行问题排查与调优
实战:亿级流量系统调优
这里以亿级流量秒杀电商系统为例:
1、如果每个用户平均访问20个商品详情页,那访客数约等于500w(一亿 / 20)
2、如果按转化率10%来算,那日均订单约等于50w(500w * 10%)
3、如果40%的订单是在秒杀前两分钟完成的,那么每秒产生1200笔订单(50w * 30% / 120s)
4、订单支付又涉及到发起支付流程、物流、优惠券、推荐、积分等环节,导致产生大量对象,这里我们假设整个支付流程生成的对象约等于20K,那每秒在Eden区生成的对象约等于20M(1200笔 * 20K)
5、在生产环境中,订单模块还涉及到百万商家查询订单、改价、包邮、发货等其他操作,又会产生大量对象,我们放大10倍,即每秒在Eden区生成的对象约等于200M(其实这里就是在大并发时刻可以考虑服务降级的地方,架构其实就是取舍)
这里的假设数据都是大部分电商系统的通用概率,是有一定代表性的。
如果你作为这个系统的架构师,面对这样的场景,你会如何做JVM调优呢?即将运行该系统的JVM堆区设置成多大呢?
练习
1、针对课上提出的问题,如何调优?
转载 鲁班学院