JVM(3)——内存相关的核心参数

1.JVM内存相关的几个核心参数图解

在这里插入图片描述

  1. -Xms:Java堆内存的大小
  2. -Xmx:Java堆内存的最大大小
  3. -Xmn:Java堆内存中的新生代大小,扣除新生代剩下的就是老年代的内存大小了
  4. -XX:PermSize:永久代大小
  5. -XX:MaxPermSize:永久代最大大小
  6. -Xss:每个线程的栈内存大小
2如何在启动系统的时候设置JVM参数?

比如说采用“java -jar”的方式启动一个jar包里的系统,那么就可以采用类似下面的格式:

java -Xms512M -Xmx512M -Xmn256M -Xss1M -XX:PermSize=128M -XX:MaxPermSize=128M -jar App.jar

3如何设置自己的项目jvm大小?

假设每天100万个支付订单,那么一般用户交易行为都会发生在每天的高峰期,比如中午或者晚上。

1.每秒多少笔交易?

平均每秒多少笔交易:100w/(24*60*60)约等于12,就是平均每秒12笔交易。
按照28比例,高峰期为中午12-13点,下午7-8点左右

平均每秒多少笔交易:100w/(2*60*60)约等于12,就是平均每秒100多笔交易。

假设我们的支付系统部署了3台机器,每台机器实际上每秒大概处理30笔订单。100/3=30

2.每个支付订单处理要耗时多久?

假设一次支付请求的处理,包含一个支付订单的创建,**大概需要1秒钟的时间。**那就是每台机器一秒钟接收到30笔支付订单的请求,然后在JVM的新生代里创建了30个支付订单的对象,做了写入数据库等处理

3.每个支付订单对象大概需要多大的内存空间?

直接根据支付订单类中的实例变量的类型来计算就可以了。

比如说支付订单类如下所示,你只要记住一个Integer类型的变量数据是4个字节,Long类型的变量数据是8个字节,还有别的类型的变量数据占据多少字节

比如支付订单这种核心类,你就按20个实例变量来计算,然后一般大概一个对象也就在几百字节的样子,我们算他大一点好了,就算一个支付订单对象占据500字节的内存空间,不到1kb。

4.每秒发起的支付请求对内存的占用

那么30个支付订单,大概占据的内存空间是30 * 500字节 = 15000字节,大概其实也就15kb而已。其实是非常非常小的。

5.总体分析

每秒30个支付请求,创建30个支付订单对象,也就占据kb级别的内存空间而已,然后接着1秒过后,这30个对象就没有人引用了,就成了新生代里的垃圾了。下一秒请求过来,不停在新生代里放入30个支付订单,然后新生代里的对象会持续的累积和增加。直到有一刻,此时占据了几百MB的空间了,可能新生代空间就快满了。然后就会触发Minor GC,就把新生代里的垃圾对象都给回收掉了,腾出内存空间,然后继续来在内存里分配新的对象。

这就是这个业务系统的运行模型。

6.对完整的支付系统内存占用需要进行预估

真实的支付系统线上运行,肯定每秒会创建大量其他的对象,把之前的计算结果扩大10倍20倍。也就是说,每秒钟除了在内存里创建支付订单对象,还会创建其他数十种对象。那么每秒钟创建出来的被栈内存的局部变量引用的对象大致占据的内存空间就在**几百KB1MB**之间。

7.支付系统的JVM堆内存应该怎么设置?

其实一般来说这种线上业务系统,常见的机器配置是2核4G,或者是4核8G。

如果我们用2核4G的机器来部署,那么还是有点紧凑的,因为机器有4G内存,但是机器本身也要用一些内存空间,最后你的JVM进程最多就是2G内存

然后这2G还得分配给方法区、栈内存、堆内存几块区域,那么堆内存可能最多就是个1G多的内存空间。然后堆内存还分为新生代和老年代,你的老年代总需要放置系统的一些长期存活的对象吧,怎么也得给几百MB的内存空间,那么新生代可能也就几百MB的内存了。

这样的话,大家可以看到,我们上述的核业务流程,只不过仅仅是针对一个支付订单对象来分析的,但是实际上如果扩大10倍~20倍换成对完整系统的预估之后,我们看到,大致每秒会占据1MB左右的内存空间。那么如果你新生代就几百MB的内存空间,是不是会导致运行几百秒之后,新生代内存空间就满了?此时是不是就得触发Minor GC了?

其实如果这么频繁的触发Minor GC,会影响线上系统的性能稳定性,

因此你可以考虑采用4核8G的机器来部署支付系统,那么你的JVM进程至少可以给4G以上内存,新生代在里面至少可以分配到2G内存空间

这样子就可以做到可能新生代每秒多1MB左右的内存,但是需要将近半小时到1小时才会让新生代触发Minor GC,这就大大降低了GC的频率。

8说说不合理设置内存的反面示例

现在假设你每秒1000笔交易,那么每秒钟系统对内存的占用增加到10MB以上,预估每秒对内存占用达到几十MB,甚至上百MB也可以,因为毕竟大促时流量激增,可能你每秒过来的1000笔交易,不再是1秒就可以处理完毕了,因为压力骤增,会导致你的系统性能下降,可能偶尔会出现每个请求处理完毕需要几秒钟,甚至几十秒的时间。然后呢,此时内存里有比如几十MB的对象都被人引用着,因为少数请求突然处理的特别慢。这个时候,如果你要再次在新生代里分配对象,那么不是会导致一次Minor GC去回收新生代,可能回收掉大量的对象之后,那少数几十MB的对象还在,因为少数请求特别的慢,后很快新生代继续被填满,再次触发Minor GC,然后少数几十MB的对象还在,此时多次之后后,就会被转移到老年代去

4如何合理设置永久代大小?

一般你设置个几百MB,大体上都是够用的

5如何合理设置栈内存大小

一般也不会特别的去预估和设置的,一般默认就是比如512KB到1MB,就差不多够了。

6老年代对象越来越多导致频繁垃圾回收

一旦老年代的垃圾对象越来越多,迟早会满,然后就会触发老年代的垃圾回收,而且这个老年代被占满的频率还很快,可能就会频繁触发老年代的垃圾回收。老年代的垃圾回收速度是很慢的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值