画图不精两个幸存者区大小是一致的。
java虚拟机的内存模型
线程共享的
1.堆内存
-
它是jvm管理内存中最大的一块。
-
它存在的唯一目的就是存储java的实例对象
-
几乎所有的实例对象都存储在java堆内存中。
-
同时它是gc进行垃圾回收的最主要区域
因为在java堆内存中的实例对象很多都是“朝生夕灭”的
所以对他进行垃圾回收的效率最高。
关于新生代的伊甸园区和幸存者区以及老年区是辅助gc进行垃圾回收的堆内存的细分区域
一般来说新new出来的对象的实例都会存储在伊甸园区,在进行一次Minor GC回收之后没有消亡的对象
会进入幸存者区域(也可能会直接进入老年区),在接下来的层层Minor GC回收中幸存者区存活的对象会慢慢进入老年区。
2.方法区
-
和堆内存一样是线程共享的,但是他又被称为non-heap(非堆)目的就是要和堆内存区分开来
-
在JDK8之前Hotspot上方法区都是以永久代来实现的。所以有些时候,程序员也将方法区和永久代混为一谈。
但是永久代仅仅是方法区的实现技术之一,并不存在于java虚拟机的内存模型之中
-
JDK8以后jHotspot以元空间(实际就是本地内存,这样的好处是方法区不在那么容易出现内存溢出问题)来代替永久代来实现方法区。这样永久代也就淡出了java内存模型之中。
运行时常量池技术
运行时常量池也是方法区的一部分
它受到方法区的内存限制,当方法区内存不足时会抛出outofmemoryerreor
线程私有的
1.程序计数器
他想对于其他区域是一块比较小的内存区域,用来记录当前线程执行的代码位置
这个区域是唯一一个在《Java虚拟机规范》中没有规定任何outofmemoryerror的区域
也就是内存溢出异常不会因为程序计数器而引起。
2.虚拟机栈
每当java要执行一个方法的时候
就对应着java虚拟机栈的一个栈贞的创建和入栈。
这个栈贞储存着这个方法的局部变量,操作数,动态链接,和方法出口等信息。
当这个方法执行完毕,就对应着这个栈贞的出栈。
如果一个线程执行过多的方法嵌套(如无跳出的递归动作)
就会引起StackOverflowError异常,原因也就是不断的栈贞入栈,而没有出栈操作导致的栈内存不足(虚拟机栈的内存空间也不是太大,而且在Hotspot中是不可以动态设置的)
3.本地方法栈
这种栈内存的功能和java虚拟机栈的功能极为相似(也可以说是本质上的不同)
java虚拟机栈是用来记录以java实现的方法的信息的。
而本地方法栈记录则是native方法的信息。
这里还需要注意的一点是在主流的Hotspot虚拟机中,已经将本地方法栈和java虚拟机栈合并到一起来实现了。(但是当我们谈论到栈内存是还是像本能一样将他们区分开来)
-----摘录自《深入理解java虚拟机》