概述:
JVM(Java Vintual Machine),简称java虚拟机,它的本质是提供了一组规范,是java跨平台的核心。之所以能跨平台,在不同的操作系统上运行,就是因为java提供了不同操作系统的虚拟机。
JVM内部主要分为三大块:类加载系统、运行时数据区、执行引擎,通常我们说内存模型指的都是运行时数据区的内存结构。
一、JVM的内存模型
方法区
方法区(No Heap):方法区是个抽象虚拟的概念,永久代(元空间)其实是方法区的实现。1.8之前叫永久代,存放在内存中,1.8以及之后直接改名为元空间,存储到直接内存,即物理内存。这块区域线程共享,静态变量+常量+类信息(类的版本,字段,方法)+构造方法 接口定义 运行时常量都存储在方法区中。运行时常量池(常量池中有一个字符串表StringTableHashSet)
堆
堆Heap:JVM调优的主要部分,虚拟机启动时创建,用于存储几乎所有的对象。
新生代:(young generation)1/3
eden:8/10 所有新创建的对象都在这个空间,如果这个空间放满了,会在from和to两个空间之间通过小GC迭代。如果整个新生代都放满了,就会移到老年代。如果都满了,就要fullGC
survicor space 幸存者空间
from:1/10
to:1/10
老年代:old generation 2/3
元空间(永久代):1.8以后直接独立出来,存储到物理内存
程序计数器
存储当前线程要执行的下一条字节码指令的地址或行号。这个区域是Java虚拟机规范中唯一一个没有内存溢出的区域。因为我们并不操作这个区域。
虚拟机栈
java线程执行方法的动态内存模型,一个线程对应一个栈,每个方法在执行的同时都会创建一个栈帧,栈帧是出入栈的最小单位,一个栈帧对应一个方法。栈不存在垃圾回收,它的生命周期和线程相同,执行完马上释放。(栈内存溢出:当线程请求的栈深度超过了虚拟机允许的最大深度时,会抛出StackOverFlowError,一般都是有方法递归调用产生的)以下是栈的内部结构:
局部变量表:存放编译器可知的各种基本数据类型,引用类型。局部变量表所需要的内存空间其实是在编译期间就完成了分配。所以在运行期间,局部变量表所占的内存是不会变的。
操作数栈:相当于一个template,存储局部变量表的数据
动态链接:
方法出口:
本地方法栈
登记native方法,在Execution Engine(执行引擎)执行时加载本地方法库
二、JVM的垃圾回收机制
三、如何判断一个对象是否可回收
未完待续....欢迎指正