实战角度分析JVM 源码(十三)

今天从实战角度分析JVM源码,首先:
 
1、使用 SourceInsight 来查看 OpenJDK 源代码
如何查看可以见一下文档。工具使用的 SourceInsight
https://cloud.tencent.com/developer/article/1585224
 
 
 
这个会耗时久点,但是可以关联全部的。
 
2、应用分析场景、堆外内存默认是多大
如果我们没有通过 -XX:MaxDirectMemorySize 来指定最大的堆外内存,那么默认的最大堆外内存是多少呢?
 
一般来说,如果没有显示的设置 -XX:MaxDirectMemorySize 参数,通过 ByteBuffer 能够分配的直接内存空间大小就是堆的最大大小。
对应参数-Xmx,真的是这么样吗?
 
 
 
 
案例分析:
 
 
1 VM 参数配置: -XX:MaxDirectMemorySize=100m
 
 
 
2、 VM 参数配置:-XX:MaxDirectMemorySize=128m
 
 
 
3、 VM 参数配置:-Xmx128m
 
 
这个地方居然报错了,果然童话里都是骗人的。
 
4、 VM 参数配置:-Xmx135m -Xmn100m -XX:SurvivorRatio=8
 
 
 
5、 VM 参数配置:-Xmx138m -Xmn100m -XX:SurvivorRatio=8
 
 
 
 
 
几个案例分析,我们得出以下结论:
没有显示的设置-XX:MaxDirectMemorySize 参数,通过 ByteBuffer 能够分配的直接内存空间大小就是堆的最大大小。 这句话是有问题的。 问题在哪里,应该是没有显示的设置-XX:MaxDirectMemorySize 参数,通过 ByteBuffer 能够分配的直接内存空间大小就是堆的最大的 可使用 的大小。
堆的最大的 可使用 的大小= 堆的最大值- 一个 Survivor 的大小(浪费的空间),所以案例 4 为什么会 OOM!
堆的最大的可使用的大小=135-10m=125m ,不能分配 128M 的对象
所以案例 5 为什么不会 OOM! 堆的最大的可使用的大小=138-10m=128m ,刚好可以分配 128M 的对象
 
 
6、源码分析
我们从代码出发,依次来找
 
 
 
 
 
 
 
 
 
7、看到上面的代码之后不要误以为默认的最大值是 64M ?其实不是的。
说到这个值得从 java.lang.System 这个类的初始化说起 上 面 这 个 方 法 在 jvm 启 动 的 时 候 对 System 这 个 类 做 初 始 化 的 时 候 执 行 的 , 因 此 执 行 时 间 非 常 早 , 我 们 看 到 里 面 调 用 了
sun.misc.VM.saveAndRemoveProperties(props):
 
 
 
 
 
 
 
8、这个地方是一个 native 方法,这个是一个本地方法,本地方法里面怎么实现的。 这个地方就需要看 JVM 的源码。
像这种本地方法,在 VM 的源码中一般都是会把包名加上,因为是给 java 用的所以前缀上还有一个 java。
大致推算出(其实已经知道了)是 JVM 的这个函数 : Java_java_lang_Runtime_maxMemory
 
 
 
 
 
 
9、这个容量其实就是每一个代的大小相加,比如 YGen+OldGen 之类
 
 
 
 
 
10、在这里可以看到, 新生代的最大值 = 新生代的最大值 - 一个 survivor 的大小
为什么会这样,因为在新生代采用复制回收算法,一个幸存者区域是浪费的,所以实际空间最大大小要减去一个交换器的大小。
而老年代是没有空间浪费的,所以还是全区域。 也得出我们设置的-Xmx 的值里减去一个 survivor 的大小就是默认的堆外内存的大小。
 
11、总结
JVM 的源码确实可以解决不少问题,但读 JVM 的源码门槛很高( C++ 的基础),同时 JVM 的源码体系非常大,如果想学源码的话,可以参考今天这个 场景,从场景切入(找几个简单的场景),读源码要有目的,这样才能做到有的放矢,才能真正的提高自己的技术水平。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

寅灯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值