运行时数据区
当java虚拟机在执行程序时会把它管理的内存分为不同的区域,这就是运行时数据区,这些区域的用途各不同,有些依赖于虚拟机的启动
有些则依赖于用户线程的启动和摧毁.
栈内存
描述java方法的执行 方法被创建时都会同时创建一个栈帧,其中存储着局部变量,动态链接,方法出口等信息
所以栈内存保存着线程中方法中短期存在的变量值和对Heap中对象的引用等.
堆内存(线程共享)
存放着几乎所有对象实例,也是GC发生的主要地方,当堆中没有内存完成实例分配并且堆无法扩展即产生了OOM
当堆中的对象不再需要使用而却没被GC回收则会导致内存泄漏
由于现在GC多数采用分代回收算法,不同代采取不同的算法处理内存中的对象
下图为java堆中的分代情况
年轻代
年轻代中分为三个区:Eden和两个Survivor,大部分的对象在Eden中产生,Eden里的对象满时会将Eden中还存活的对象复制到Survivor区其中的一个,当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor区也满了的时候(全满),从第一个Survivor区复制过来的并且此时还存活的对象,将被复制到“年老区”
年老代
年老代中存放的是从年轻代存活下来的对象,生命周期大多较长
永久代
用于存放静态文件,如Java类、方法等。
持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate等, 在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。
PC寄存器
当前线程所执行的字节码的行号指示器
即其中保存着当前线程目前在处理字节码中的进度,可以改变PC寄存器中的数值使JAVA选取下一个执行的字节码
本地方法栈
与栈内存相似,只不过虚拟机栈执行的是java方法,而本地方法栈执行的是Native方法
方法区(线程共享)
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等
方法区中包含着
运行时常量池
用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中
网友评论