简述jvm内存模型及垃圾回收

一,java内存模型

jvm内存模型见下图:
在这里插入图片描述

1,程序计数器

线程是cpu调度的最小单位,当多线程竞争cpu时间片段时,当线程切换时能正确的切回到指定位置,需要一个计数器记录当前执行的字节码的地址。
因此,程序计数器是线程私有的一块较小的内存空间,其可以看做是当前线程所执行的字节码的行号指示器。

2,本地方法栈

属于线程私有,存放java的本地方法调用,java本地方法指的时native修饰的那些方法,其调用的是c,c++等方法,存放在本地方法库中。

3,java虚拟机栈

属于线程私有,每个方法在执行的时候会创建一个栈帧,存放局部变量表,操作数栈,动态连接方法,返回地址等信息。一个方法的调用过程相当于一个栈帧的压栈和出栈。
虚拟机栈有两种异常情况:StackOverflowError 和 OutOfMemoryError。我们知道,一个线程拥有一个自己的栈,这个栈的大小决定了方法调用的可达深度(递归多少层次,或嵌套调用多少层其他方法,-Xss 参数可以设置虚拟机栈大小),若线程请求的栈深度大于虚拟机允许的深度,则抛出 StackOverFlowError 异常。此外,栈的大小可以是固定的,也可以是动态扩展的,若虚拟机栈可以动态扩展(大多数虚拟机都可以),但扩展时无法申请到足够的内存(比如没有足够的内存为一个新创建的线程分配栈空间时),则抛出 OutofMemoryError 异常。

4,堆内存

存放创建的对象实例,gc优化主要是优化堆内存。堆内存又可分为新生代和老年代。见下图。
在这里插入图片描述
新生代用于存放刚创建的对象以及年轻的对象,如果对象一直没有被回收,生存得足够长,对象就会被移入老年代。新生代又可进一步细分为 eden、survivorSpace0 和 survivorSpace1。刚创建的对象都放入 eden,s0 和 s1 都至少经过一次GC并幸存。如果幸存对象经过一定时间仍存在,则进入老年代。

5,方法区

方法区与Java堆一样,也是线程共享的并且不需要连续的内存,其用于存储已被虚拟机加载的 类信息、常量、静态变量、即时编译器编译后的代码等数据。

二,内存异常情况及解决方案

1、Java堆溢出 (OOM)

Java堆用于存储对象的实例,只要不断地创建对象,并且保证GC roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。
  在这里插入图片描述
  要解决这个异常,一般先通过内存映像分析工具对堆转储快照分析,确定内存的对象是否是必要的,即判断是 内存泄露 还是 内存溢出。如果是内存泄露,可以进一步通过工具查看泄露对象到GC Roots的引用链,比较准确地定位出泄露代码的位置。如果是内存溢出,可以调大虚拟机堆参数,或者从代码上检查是否存在某些对象生命周期过长的情况。

2、虚拟机栈和本地方法栈溢出 (SOF/OOM)

2.1 SOF
  
  如果线程请求的栈深度大于虚拟机栈允许的最大深度,将抛出StackOverflowError异常。我们知道,每当Java程序启动一个新的线程时,Java虚拟机会为它分配一个栈,并且Java虚拟机栈以栈帧为单位保持线程运行状态。每当线程调用一个方法时,JVM就压入一个新的栈帧到这个线程的栈中,只要这个方法还没返回,这个栈帧就存在。 那么可以想象,如果方法的嵌套调用层次太多,比如递归调用,随着Java虚拟机栈中的栈帧的不断增多,最终很可能会导致这个线程的栈中的所有栈帧的大小的总和大于-Xss设置的值,从而产生StackOverflowError溢出异常。
  
2.2 OOM
 如果虚拟机在拓展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。在虚拟机栈和本地方法栈发生OOM异常场景如下:当Java 程序启动一个新线程时,若没有足够的空间为该线程分配Java栈(一个线程Java栈的大小由-Xss设置决定),JVM将抛出OutOfMemoryError异常。

三:垃圾回收

详见 图解java垃圾回收
https://blog.csdn.net/justloveyou_/article/details/71216049

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值