##JVM 内存模型
内存模型分为:方法区,堆区,虚拟机栈,本地方法栈,程序计数器.
方法区(线程共享)
存储了每一个类的结构信息,例如运行时常量池( Runtime Constant Pool)、字段和方法数据、构造函数和普通方法的字节码内容、还包括一些在类、实例、接口初始化时用到的特殊方法.(jdk7 hotspot 中采用来实现永久带,1.8采用元数据区来实现.)堆区(线程共享)
存放对象的区域虚拟机栈
方法运行时创建的栈帧,用于存放局部变量,操作数栈,动态链接,方法出口,每个方法局部变量是隔离的.本地方法栈
native方法运行时,存放局部变量,操作数栈,方法出口的信息.程序计数器
当前程序执行字节码的指示器,通过改变计数器来选取下一条需要执行的字节码指令.元数据区
作用类似用永久带
总结:JVM 内存模型,分为5块.方法区,堆区,虚拟机栈,本地方法栈,程序计数器.我的理解是,方法区的作用类似一个hashTable.里面记录的是各个类的骨架信息,执行方法的程序计数器指令的位置,以及一些其他必要参数.通过这些参数,在方法调用的时候,通过方法区的指引,执行相关的程序指令,创建用于该方法的虚拟机栈或者本地方法栈来处理一些过程数据,最后返回相应的结果给到调用者.这里虚拟机栈创建的对象存放于堆区,方法区修改对象,实际上是修改的堆中的对象.但局部变量在虚拟机栈中,所以方法里面修改局部变量,其实是不影响全局变量的.但是修改对象就会.原因就在这里.
所以,虚拟机垃圾回收的主要集中在堆区.对方法区也有可能触发.方法区申请新的内存区域不足是,会抛出相应异常.
垃圾回收区域:新生代,老年代,永久带(元数据区). 永久带垃圾回收效率低.
##JVM GC回收机制
判断是否为垃圾的算法
- 引用标计算法
每一个对象,对有一个引用计数器.存在引用则计数器+1,缺点:引用计数器不能解决循环引用的问题,而且引用计数器本身存在内存开销. - 根搜索算法
将某些特殊的对象定义为GC Root . 某个对象 与其他所有对象的引用关系组成一条链. 如果组成的这条链无限延伸都没有GC根相连,则证明该链上的所有对象都是可以回收的垃圾对象.GC根对象指的是:虚拟机栈中引用的对象,方法区常量引用的对象,方法区静态属性引用的对象,本地方法栈中JNI引用的对象,活跃的线程.(其实就是正在运行的数据+静态数据)
执行垃圾回收的算法
- copy 算法(年轻代)
- 标记-清除/整理 算法
spothot 提供的垃圾回收器
- SerialGC 串行(copy)垃圾回收器(年轻代)
- SerialOldGC 串行(老年代)
- ParNewGC 并行(copy)垃圾回收器(年轻代)
- ParallelGC 并行(copy),提高吞吐量.(年轻代)
- ParallelOldGC 并行(copy),(老年代)
- ConcMarkSweepGC 标记清除(老年代) ,新生代 ParNewGC
- G1GC 新生代/老年代(G1)
##JVM 性能调优
应尽量避免FULL GC
- 避免出现Full GC
- 根据对应的场景选取适配的垃圾回收器
- 配置合理的内存整理次数.