JVM内存分类
- 线程私有内存
程序计数器(Program Counter Register)
Java虚拟机栈(JVM Stack)
本地方法栈(Native Method Stack) - 多线程共享内存
堆(Heap)
方法区(Method Area)
运行时常量池
程序计数器
–Program Counter Register, 一块小内存,每个线程都有
–PC存储当前方法(线程正在执行的方法称为该线程的当前方法 )
–当前方法为本地(native)方法时, pc值未定义(undefined)
–当前方法为非本地方法时,pc包含了当前正在执行指令的地址
–当前唯一一块不会引发OutOfMemoryError异常
通俗的讲:程序计数器用来记录当前方法执行到哪一步了,等当前线程重新获得CPU执行权时(线程切换),接着上次记录的位置接着往下执行
JVM 栈(JVM Stack,Java 栈)
–每个线程有自己独立的Java虚拟机栈,线程私有,-Xss设置每个线程堆栈大小。
–Java方法的执行基于栈,每个方法从调用到完成对应一个栈帧在栈中入栈、出栈的过程。栈帧存储局部变量表、操作数栈等,局部变量表存放在方法中存在“栈”里面的东西。
–栈的深度超过虚拟机规定深度,StackOverflowError异常,无法扩展内存,OutOfMemoryError异常。
本地方法栈(Native Method Stacks)
存储native方法的执行信息,线程私有,当Java程序调用C程序的信息会存储在此栈中。 VM规范没有对本地方法栈做明显规定。栈的深度超过虚拟机规定深度,StackOverflowError异常,无法扩展内存,OutOfMemoryError异常。
堆(Heap)
–虚拟机启动时创建,所有线程共享,占地最大
–对象实例和数组都是在堆上分配内存
–垃圾回收的主要区域
–设置大小 (-Xms 初始堆值,-Xmx最大堆值)
–引发的异常 (无法满足内存分配要求,OutOfMemoryError异常
)
方法区(Method Area)
–存储JVM已经加载类的结构,所有线程共享(运行时常量池、类信息、常量、静态变量等)
–JVM启动时创建,逻辑上属于堆(Heap)的一部分
–很少做垃圾回收
–引发的异常(无法满足内存分配要求,OutOfMemoryError异常
)
运行时常量池(Run-Time Constant Pool)
–Class文件中常量池的运行时表示(每个类加载进方法区的时候,类中的常量会被加载到常量池中)
–属于方法区的一部分
–动态性( Java语言并不要求常量一定只有在编译期产生,比如String.intern方法)
–引发的异常(无法满足内存分配要求,OutOfMemoryError异常
)