一、运行时数据区域
- 程序计数器:当前线程所执行字节码的行号的指示器。字节码解释器工作时就是通过改变这个计数器的值来选择下一条需要执行的字节码指令、分支、循环、跳转、异常处理。Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的。在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令,因此为了线程切换后能恢复到正确的执行位置,每个线程都需要一个独立的程序计数器。各个线程之间的程序计数器互不影响,独立存储,我们称为线程私有的内存。
- Java虚拟机栈:与程序计数器一样,也是线程私有的,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。局部变量表存储了编译器可知的各种基本数据类型、对象引用
- 堆:所有线程共享的一块内存区域,所有的对象实例和数组都要在堆上分配。Java堆是垃圾收集器管理的主要区域。
- 方法区:与Java堆一样,是线程共享的区域。用于存储已经被虚拟机加载的类信息,常量、静态变量,即时编译器编译后的代码等数据。
二、HotSpot虚拟机对象探秘
2.1 对象的创建
虚拟机遇到new指令 ->检查类是否被加载、解析和初始化 ->分配内存
三、垃圾收集器与内存分配策略
3.1 GC算法
- 引用计数算法:给对象添加一个引用计数器,每当有一个地方引用它,计数器值就加1;当引用失效的时候,计数器值减1。任何时刻计数器为0的对象就是不可能再被使用的,但是不能解决对象相互引用的问题;
-
可达性分析算法: