用户8522区域 | 描述 | 线程私有 | 如何溢出 |
程序计数器 | 为了线程切换后能恢复到正确的执行位置,每个线程都要有一个独立的程序计数器。 | ✅ | 唯一一个不会内存溢出的地方 |
虚拟机栈 | 1. 每个方法执行的时候,Java虚拟机都会同步创建一个栈帧用于存储局部变量表、操作数栈、方法出口等信息。 2. 每一个方法从调用到执行完毕都对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。 3. 局部变量表存储了编译期可知的各种Java基本数据类型和对象引用。 | ✅ | 1. 线程请求的栈深度大于虚拟机所允许的深度时抛出 StackOverFlowError异常。 2. 栈扩容时无法申请到足够内存的时候抛出 OutOfMemoryError。 |
本地方法栈 | 和虚拟机栈类似,本地方法栈是为本地(Native)方法服务的 | ✅ | 同【虚拟机栈】 |
方法区 | 线程共享,用于存放被虚拟机加载后的类型信息、常量、静态变量、即时编译器编译后的代码缓存数据。 注:运行时常量池、元空间都属于方法区的一部分。 | ❌ | 无法满足新的内存分配会抛出 OutOfMemoryError |
堆(垃圾收集的主要区域) | 1. 基本上所有的对象都是在堆上分配的。 2. Java堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连续的。 | ❌ | 无法满足新的内存分配会抛出 OutOfMemoryError |
直接内存 | NIO通过使用Native函数库直接分配对外内存。不受Java堆大小限制,但是受机器的物理内存限制。 | ❌ | 无法满足新的内存分配会抛出 OutOfMemoryError |
算法 | 描述 | 备注 |
引用计数算法 | 当某个对象被引用的时候引用计数器就加一,引用失效时就减一,当没有引用的时候就说明可以被回收了。 | 几乎没有使用它的,因为它无法解决循环依赖的问题。 |
可达性分析 | 某些对象被定义为根(GC Roots),从GC Roots向下搜索的路径成为“引用链”,如果某个对象到GC Roots间没有任何引用,那说明它不可达,它就可以被回收了。 | 目前都是用这种算法。 |