JVM内存区域划分

2 篇文章 0 订阅

JVM内存区域划分

  在JAVA虚拟机中,内存区域主要分为线程共享区域(存在线程安全问题)和线程私有区域(无线程安全问题)。

JVM内存划分

线程共享区域

  其中线程共享区域分为堆和方法区,堆中主要用来存储跟实例对象相关的数据(例如,new出来的对象实例,JDK1.7后字符串常量也加入了堆),方法区主要存储跟类本身相关的信息(例如,类型信息,字段信息,方法表等)。

线程共享区域划分

GC堆

  堆通常又被称为GC堆,这里时垃圾回收最主要的区域,堆中又可以划分为新生代(Young)和老年代(Old)。其中新生代划分为三部分,分为Eden区、Survivor From区、Survivor To区(内存区域分配为8:1:1,这样能够使得有大部分的空间能够new对象),GC最频繁的区域就是Eden和Survivor From区,被称为minor GC。新产生的对象直接进入Eden区域,GC时会清理掉Eden和Survivor From区中死亡的对象(当前不再使用到的对象),仍然存活的对象会被复制到Survivor To区(每一次复制后年龄会增加1),如果年龄超过了设定的阈值,或者To区空间不够时,就会进入老年代(比如设定为15岁,超过了15岁后,就直接进入老年代)。一次清理过后,会将To区域的对象复制到From区,这样一次minor GC就完成了。老年代空间不足时,会先尝试触发Minor GC,如果之后空间还不足,则触发Major GC对老年代也进行GC。

minor GC

方法区

  方法区主要存储解析Class文件后获取相关信息。方法区会存储已被虚拟机加载的类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据(还包括符号引用:例如,一个类引用了另一个类,此时被引用类还未被加载,此时就用一个符号来代替表示)。

线程私有区域

  线程私有区域主要是记录线程自身运行状态的栈。包括程序计数器、本地方法栈、虚拟机栈。

线程私有区域

  程序计数器:当前线程所执行的字节码的行号指示器,完成分支、循环、跳转、异常处理、线程恢复等功能。记录当前线程运行到哪里了,下一步执行什么命令,以及上下文切换后继续执行哪里。

  本地方法栈:调用本地方法(有native关键字的方法)。

  虚拟机栈:所有java方法的调用。

虚拟机栈

栈帧

  每一次进入方法的调用都会压入一个栈帧,栈帧中包含局部变量表、操作数栈、动态链接、方法返回地址。

  局部变量表:存放编译时可知的数据类型(8大基本类型:int、float、short、long、char、byte、boolean、double)及对象引用(不是对象本身,类似地址来找到所需要的对象)。

  操作数栈:存放中间过程的计算结果。

  动态链接:调用其他方法时,链接到调用方法的地址。

  方法返回地址:下一条指定执行哪里,以及返回值传递。

  无论是正常return,还是throw Exception,都会将栈帧弹出。当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候,会抛出 StackOverFlowError 错误。如果栈的内存大小可以动态扩展,但是虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值