Java进程的内存占用[译] Part 3 - AndreiPangin

7 篇文章 0 订阅

原视频链接:不存在的网站,翻译此视频并发布已获得原作者同意。

Java进程的内存占用[译] Part 2 - AndreiPangin

JVM运行时 - JIT 编译器

在这里插入图片描述
还有什么其他JVM内存占用部分?JIT编译器!又分为两部分:专门用于 JIT 编译的代码和编译器。
在这里插入图片描述
Code Cache(代码缓存)存放了编译后的代码,不只是method,所以即使你完全打开了JIT编译,解释器和一些运行时stubs(这部分知识我没接触过)也放在Code Cache。有两个选项用于控制初始化(-XX:InitialCodeCacheSize)和最大(-XX:ReservedCodeCacheSize)Code Cache 大小。
同样的,类似GC,这儿也有另外的一个部分,许多的JIT 编译算法也需要额外的内存,用来构建IR Graph,基本上运行编译算法需要一部分内存。此内存大致与编译器线程数成正比。

这里给大家一个问题,GraalVM(属于JVM的一种,是OpenJDK其中的一种实现)是否也需要Code Cache、Compiler Arenas?你们是怎么认为的呢?事实上,GraalVM是用Java写的,运行的时候就像一个普通的Java应用,所以它在Java堆中构建了自己的结构,而不是堆外内存(off-heap memory)。
在这里插入图片描述
所以Graal是没有Compiler Arenas的,但是编译后的代码仍然放在Code Cache中。
在这里插入图片描述
Code Cache有多大呢?HotSpot有两个JIT编辑器:C1和C2,或者C1和Graal。为了编译更多的代码,默认的Code Cache大小的增长因子是5,反过来也一样,所以如果由于何种原因,禁用了TieredCompilation(-XX:-TieredCompilation,分层编译),CodeCache大小会小很多,所以会变成48M,对于编译大型项目是不够的,有时候240M都不够。有一天我们发现我们一个服务发生了性能下降,是由于Code Cache的问题,当Code Cache增长到限制值,HotSpot开始丢弃早期编译的代码,但因为这些代码属于刚刚编译,所以重新编译了一次,您猜怎么着,这些代码经历了编译、丢弃、再编译、再丢弃,如此循环,浪费了很多时间、CPU资源。
在这里插入图片描述
所以在这次异常事件后,我们开始监控Code Cache 内存池,和其他内存池一样,这些统计信息是可以很容易获取到的,都是些标准的MX Bean,可以通过JMX获取。例如我们用Java Mission Controll连上后,切换到内存选项卡,你就能看到Code Cache、Metaspace等等使用的内存总量。不过并非所有的内存池都是这么简单就能监控到的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值