JVM
JVM 后台运行的系统进程
虚拟机线程
这个线程等待JVM到达安全点操作出现. Stop the world 垃圾回收、线程栈dump、线程暂停、线程偏向锁解除.
周期性任务线程
这线程负责定时器事件(中段),用来调度周期性操作的执行
GC线程
不同的GC
编译器线程
将字节码编译成本地码
信号分发线程
这个线程发送到JVM的信号并调用适当的JVM方法处理.
JVM 内存区域
线程私有区域
程序计数器
计数器记录的是虚拟机字节码指令的地址(当前的地址)
虚拟机 栈 知乎介绍
局部变量表 里面会包括 这个方法的临时变量和入参数信息
操作数栈 操作数栈
当一个方法刚刚开始执行时,其操作数栈是空的,随着方法执行和字节码指令的执行,会从局部变量表或对象实例的字段中复制常量或变量写入到操作数栈,
再随着计算的进行将栈中元素出栈到局部变量表或者返回给方法调用者,也就是出栈/入栈操作
比方说 int result = parameter1 + parameter2
实际上就是iadd, 它将两个int添加在一起.要使用它,你在堆栈上推两个值,然后使用它
1
2
3iload_0 # Push the value from local variable 0 onto the stack
iload_1 # Push the value from local variable 1 onto the stack
iadd # Pops those off the stack, adds them, and pushes the result比方说 int result = parameter1 + parameter2 + parameter3
1
2
3
4
5iload_0 # Push the value from local variable 0 onto the stack
iload_1 # Push the value from local variable 1 onto the stack
iadd # Pops those off the stack, adds them, and pushes the result
iload_2 # Push the value from local variable 2 onto the stack
iadd # Pops those off the stack, adds them, and pushes the result动态链接
Java虚拟机栈中,每个栈帧都包含一个指向运行时常量池中该栈所属方法的符号引用.这些符号引用一部分会在类加载阶段或者第一次使用时就直接转化为直接引用,这类转化称为静态解析。另一部分将在每次运行期间转化为直接引用,这类转化称为动态连接。
方法返回
一个方法可能有两种方法退出 正常返回和出现异常返回.一般来说,方法正常退出时,调用者的PC计数值可以作为返回地址,栈帧中可能保存此计数值。而方法异常退出时,返回地址是通过异常处理器表确定的,栈帧中一般不会保存此部分信息。
本地方法区
方法返回时可能需要在当前栈帧中保存一些信息,用来帮他恢复它的上层方法执行状态。
线程共享区
Java堆
从GC的角度来说可以分为 新生代、老年代
新生代
新生代占用堆区1/3空间. 新生代分为 Eden、ServivorFrom、ServivorTo 三个区域.分配的比例是 8:1:1.在新生代发生的垃圾被称为
老年代
老年代的数据比较的稳定,所以MajorGC 不会平凡的发生 然后使用的算法是标记-清除算法. 在触发Major Gc之前一定会触发一次MinorGC
垃圾回收算法
标记-清除
没有连续的可用的内存空间,会有很多的碎片.
复制算法
将内存分为同等大小的两块.当某一块内存满后将尚存活的对象复制到另一块上去.对象的Age会+1.默认年龄到达15会移动到老年区.
标记整理算法
标记阶段和Mark-Sweep算法相同,标记后不是清理对象,而是将存活对象移向内存的一端.
方法区
主要存放类信息和meta-data. 在Java8中永久带已经被元空间的概念取代.元空间不存在虚拟机中,而是使用本地内存.在默认情况下元空间的大小仅受本地内存限制.
Java的四种引用类型
强引用
最常见的就是强引用.当一个对象(Object)信息被赋值给一个引用(Reference)时,就是强引用.当处于可达状态时不可能被回收的
软引用
SoftReference.当内存不够时候会被回收
弱引用
WeakReference 当垃圾回收机制一运行总会回收该对象占有的内存. 当我们创建一个ThreadLoad的值的时候,实际上是加入到ThreadLocalMap<WeakReference<ThreadLocal<?>>, Object> 中
虚引用
需要PhantomReference 类实现,它不能单独使用, 必须和引用队列联合使用.虚引用的主要作用是跟踪对象被垃圾回收的状态.
垃圾回收算器
针对不同的内存区域采用不同的垃圾回收算器.
- 年轻带:
Serial 单线程的垃圾收集器. STW. 复制
ParNew Serial的多线程版本.STW. 复制
Parallel scavenge 多线程的垃圾收集器. 通过自适应的调节策略来达到最大的吞吐量. STW. 复制
- 年老带:
Serial Old 是Serial老年区版本 单线程 STW. 标记整理
Parallel Old 是Parallel scagenge老年区版本 STW 标记整理
CMS
初始标记 (只是标记一下GC Roots能够直接关联的对象 STW)
并发标记
重新标记
并发清除(和用户线程一起工作 不需要暂停工作线程)
G1
基于标记-整理算法 不产生内存碎片
非常准确控制停顿时间,在不牺牲吞吐量前提下实现低停顿垃圾回收