1. JVM内存区域

JVM内存主要可以分为五个区域:程序计数器、虚拟机栈、本地方法栈、堆、方法区。其中除了堆和方法区是线程共有的,其他几个区域都是线程私有的:

1、程序计数器

程序计数器是一块较小的内存,通过这个计数器来选取下一条需要执行的字节码指令。Java虚拟机的多线程是通过线程之间切换来轮流获得处理器的执行时间的,每个线程都有自己独立的程序计数器,它们互不影响,也就是线程私有的。如果执行的是Java方法,这里存放的是指令地址,如果执行的是Native方法,这里的值为空(Undefined)。并且这个区域不会出现OutOfMemoryError

2、虚拟机栈

虚拟机栈也是线程私有的,虚拟机栈描述的是Java方法执行的内存模型,执行每个方法的时候都会创建一个栈帧,用来存储局部变量表、操作数栈、方法出口等信息。局部变量表中存放了各种基本数据类型,对象引用类型,局部变量表在编译期间完成分配。

这个区域有两种异常情况:如果线程请求的栈深度大于虚拟机容许的最大深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展,但是扩展时无法申请到足够的内存,抛出OutOfMemoryError异常。

3、本地方法栈

本地方法栈与虚拟机栈的作用类似,只不过是虚拟机栈是为执行Java方法服务,而本地方法栈是为执行Native方法服务。

4、堆

Java堆是由所有线程共享的一块内存区域,在虚拟机启动时创建,并且也是Java虚拟机管理管理的内存中最大的一块。Java堆主要用于存放对象实例以及数组,Java堆是垃圾回收的主要区域,也被成为“GC”堆。关于垃圾回收在下一篇博客中我会详细介绍。

5、方法区

方法区也是各个线程共享的内存区域,用于存储已经被虚拟机加载的类信息、常量、静态变量等数据。这个区域也会存在垃圾回收,不过回收的目标主要是针对常量池和对类型的卸载,不过由于类型的卸载条件比较苛刻,所以回收成绩难以令人满意。

原文链接:https://blog.csdn.net/buptwds/java/article/details/51933379

里面还介绍了对象访问的两种方式, 使用句柄和使用直接指针, HotSpot虚拟机使用的是直接指针

2. 垃圾回收机制

https://www.cnblogs.com/czwbig/p/11127159.html

https://www.jianshu.com/p/12544c0ad5c1  三色标记法

垃圾回收算法: 引用计数, 分代回收, 复制算法, 标记-清除, 标记-整理

垃圾回收的区域: GC主要发生在堆区和方法区