JVM系列-参数调优1

说到JVM的参数调休,一定得知道JVM的内存结构,理解JVM内存结构的参数调优都是耍流氓,参数调优至少要知道调的是什么,优化的是什么。

JVM内存和物理机内存其实是有很多对应关系的,JVM的内存也受到物理机内存的约束,毕竟JVM内存是基于物理内存虚拟出来的东西,大体来说,

JVM内存分为heap区、stack区、method区、程序计数器,再细分一点的话heap区又分为新代和老代,栈区又分为java栈和本地方法调用栈,但是这里要注意的是JVM规范中并没有对本地方法栈实现方法和数据结构做强制规定,虚拟机的实现者可以自由实现它,在HotSpot虚拟机中直接就给二者合二为一了。内存结构示意图大致如下:

(图片来源于网络:云时代架构公众号)

程序计数器/栈

      对于程序计数器区,主要是为了多线程情况下在CPU进行时间片轮转执行之后能回到之前线程的执行地方继续执行,而执行依赖的执行现场由java 栈来保存,java里的栈是每个线程所私有的,没有并发同步问题。也因为程序计数器区并不会因为程序的执行而变大所以这个区域是唯一一个不会发生OOM的区域;前面我们说到,java线程在执行的时候会记录当前的执行现场以便于后面恢复执行现场,典型的就是递归调用,我们都知道递归调用其实就是方法的调用逻辑从上到下而方法的返回逻辑从下到上,每计算一层调用的时候需要依赖下层结果,这个下层结果存储在哪里?就是栈了,这也就是为什么有时候在代码里用到递归的时候,如果运用不合理比如出现了死循环或者递归终止条件设置有问题导致程序一直递归执行下去的时候会报stackoverflow的原因。

方法区

   方法区存储的包括静态变量、常量池(编译期生成的字面量和常量)、方法信息、名称信息、字段信息、以及编译后的代码信息,方法区是全局的,换句话说方法区存储的东西是所有线程共享的,也存在线程安全问题,必要的时候需要采取一定得同步手段;那么前面说到了方法区存储的信息包括哪些,由此可以看出方法区存储的东西并不是固定的而是和我们的程序设计有关,所以在项目里类太多、静态变量太多的时候可能出现OOM,错误就是java.lang.OutOfMemoryError: PermGen,当然这个是在java8之前的情况,在java8里去掉了Perm区改成了Metadata区,最大的区别是Perm区是java虚拟内存的一部分,大小受到分配给java内存大小限制,而Metadata区大部分class元数据存储在本地内存,从某种意义上来说更不容易发生java.lang.OutOfMemoryError: PermGen这个类似错

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值