JVM原理解读——内存分区
我们把jvm虚拟机管理的内存区域叫做运行时数据区,把不由jvm虚拟机管理的的区域叫做直接内存或本地内存
运行时数据区在逻辑上总共分为5个分区:堆、程序计数器、方法区、虚拟机栈、本地方法栈
其中所有线程共享堆和方法区,每个线程都有自己的程序计数器、虚拟机栈和本地方法栈
1、堆(Heap)
堆是JVM内存中占用最大的一块内存空间
主要用来存储大部分的对象和数组
堆内存被分为新生代和老年代,新生代又被分为Eden、From Servivor和To Survivor,新生代默认比例8:1:1
jvm申请堆内存的时候,堆只占用堆内存的一部分,方法区中的部分数据也会占用堆内存
2、程序计数器(Program Counter Register)
程序计数器占用了JVM内存中很小的一块内存空间
主要用来存线程执行的字节码地址
3、方法区(Method Area)
方法区只是一个概念,在hotspot中由两部分组成,其中一部分存放在堆中,占用JVM申请的堆内存(你没看错,是放在堆内存中了,物理上占用的堆内存,但逻辑上属于方法区,相当于原来给堆申请的内存中存了堆和方法区两块数据,所以为了区别堆和方法区,有时候也把方法区叫做非堆);另一部分存放在元空间,直接占用服务器的物理内存(也叫直接内存)
所以就我理解,元空间只是实现了方法区的一部分,因为方法区还有一部分在堆内存中
存放在元空间的数据是静态常量池(或者叫class文件常量池),静态常量池中主要包括字面量(字符串和基本类型常量)和符号引用(类和方法的全限定名)
存放在堆中的数据是运行时常量池(数据来源于静态常量池),运行时常量池中有一个特别的区域叫字符串常量池,存储的是字符串对象的引用(也就是字面量的内存地址,这个地址是运行时常量池初始化时,根据静态常量池中的字符串字面量生成的)。基本类型常量字面量也在运行时常量池中
4、虚拟机栈(VM stack)
主要存储局部变量、操作数栈、动态链接方法和返回地址
5、本地方法栈(Native Method Stack)
主要管理本地native方法的调用