最近学习了下JVM内存结构,再此做了一个总结,希望能帮助大家。
JVM是按照运行时数据的存储结构来划分内存结构的,JVM在运行java程序时,将它们划分成几个不同格式的数据,分别存储在不同的区域,这些数据统一称为运行时数据。
在Java虚拟机规范中将java运行时数据主要划分为6个区域。
1、PC寄存器
主要用来保存当前正在执行程序的内存地址。这个应该很好理解,就是保存当前程序执行的内存指针。
2、Java栈
java栈总是和线程关联在一起,当创建一个线程时,JVM就会为这个线程创建一个对应的Java栈,在这个栈中又会有很多的栈帧,这些栈帧是和方法关联的,每运行一个方法就会创建一个栈帧,每个栈帧会含有一些方法的局部变量、操作栈和方法返回值等信息。
3、堆
java堆是存储对象的地方,它是JVM管理java对象的核心区域,这个是程序员最关系的一个区域,一般对程序的运行影响较大,若对象创建过多,则可能引起OOM问题。
堆是被所有java线程共享的,所以对它的访问需要注意同步问题,方法和对应的属性都需要保证一致性。
4、方法区
JVM方法区是用于存储类结构信息的地方,在将一个class文件解析成JVM能识别的几个部分,这些不同的部分在这个class被加载到JVM时,会被存储在不同的数据结构中,其中的常量池、域、方法数据、构造函数,包括类中的专用方法、实例初始化、接口初始化都存储在这个区域。
方法区其实属于java堆的一部分,就是通常所说的java堆中的永久区(PermGen)。这个区域可以被所有线程共享,它的大小可以通过参数来设置。
5、运行时常量池
运行时常量池是方法区的一部分,Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到常量池中。
6、本地方法栈
本地方法栈是为JVM运行native方法准备的空间,它和java栈的作用类似,很多native方法是用c语言实现的,通常也被叫做C栈。JVM没有对这个区域严格限制,可以由JVM实现着自由实现,但是和其他区域一样,同样会抛出OutOfMemoryError和StackOverflowError异常。