jvm内存结构

jvm比较重要的内存区域
方法区:在java的虚拟机中有一块专门用来存放已经加载的类信息、常量、静态变量以及方法代码的内存区域,叫做方法区。
常量池:常量池是方法区的一部分,主要用来存放常量和类中的符号引用等信息。
堆区:用于存放类的对象实例。
栈区:也叫java虚拟机栈,是由一个一个的栈帧组成的后进先出的栈式结构,栈桢中存放方法运行时产生的局部变量、方法出口等信息。当调用一个方法时,虚拟机栈中就会创建一个栈帧存放这些数据,当方法调用完成时,栈帧消失,如果方法中调用了其他方法,则继续在栈顶创建新的栈桢。
除了以上四个内存区域之外,jvm中的运行时内存区域还包括本地方法栈程序计数器

1)堆

所有通过new创建的对象的内存都在堆中分配,堆的大小可以通过-Xmx和-Xms来控制。
堆被划分为新生代旧生代,新生代又被进一步划分为EdenSurvivor区,最后Survivor由From Space和To Space组成

新生代。新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,
新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例

旧生代。在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。

2)栈
每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数和中间结果。

3)本地方法栈
用于支持native方法的执行,存储了每个native方法调用的状态

4)方法区
存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。

绝大部分 Java 程序员应该都见过 “java.lang.OutOfMemoryError: PermGen space “这个异常。这里的 “PermGen space”其实指的就是方法区。方法区和“PermGen space”又有着本质的区别。前者是JVM的规范,而后者则是JVM规范的一种实现(HotSpot)

HotSpot 1.7中,使用永久代来实现方法区,

永久代,已经取消,JDK8 HotSpot JVM现在使用了本地内存来存储类元数据,被称为Metaspace。

1 移除永久代是为融合HotSpot JVM与 JRockit VM而做出的努力,因为JRockit没有永久代,不需要配置永久代。

2 现实使用中易出问题
由于永久代内存经常不够用或发生内存泄露,爆出异常java.lang.OutOfMemoryError: PermGen