JVM
JVM运行时数据区
方法区和堆是所有线程共享的区域;
而java栈、本地方法区、程序计数器是运行时线程私有的内存区域
java堆(Heap)
是java虚拟机管理的内存中最大的一块,java堆是被所有线程共享的一块内存区域,在虚拟机启动创建时创建。此内存区域的唯一目的就是存放对象实例,几乎所以的对象实例都在这里分配内存。
方法区(Method Area)
方法区(Method Area)与java堆一样,是各个线程共享的内存区域,它用来存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
程序计数器(Program Counter Register)
程序计数器是一块很小的内存空间,它的作用可以看作是当前线程执 行的字节码的行号指示器。
jvm栈(JVM Stacks)
与程序计数器一样,java虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,它的生命周期与线程相同。虚拟机描述的是java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。没一个方法被调用直至完成的过程,就对应着一个帧栈在虚拟机中从入栈到出栈的过程。
本地方法区(Native Method Stacks)
本地方法区(Native Method Stacks)与虚拟机栈所发挥的作用是非常类似的,其区别不过是虚拟机栈为虚拟机执行的java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用Native方法服务。
JVM内存模型
老年代
年轻代
刚创建的对象,年龄比较小的对象,如果说新生代不够放,那边就通过担保机制存放到老年代。如果对象在GC后没有被回收,如果Eden区不够用,会存复制到S区,意思就是说Eden区的对象是朝生昔死的。S区分为两块。
如何判断对象存活
引用计数法:对象被引用+1,没有引用就是0,互相引用除外。
可达性分析:GCRoot 虚拟机栈本地变量表、static、常量引用、本地方法栈中的变量,判断是否间接或者直接可以追溯到的对象。
问题
为什么常量池属于方法区的一部分
因为运行时常量池是在方法区进行分配的
方法存放在哪个区域
每个对象实例都包含方法,如果是存储在堆中的,太浪费空间。所以说,方法应该是一个模板,存放在方法区,最为合理
是否线程共享区域
线程共享:方法区、运行时常量池、堆
线程安全:程序计数器、java栈、本地方法栈
如果一个线程在执行普通方法时,调用了本地方法,怎么描述
在普通方法调用本地方法的时候,通过动态链接指向本地方法栈帧