JVM内存管理

一、JVM内存划分

方法区(持久代):存放要加载的类信息、类中静态变量、final常量、方法信息等;class对象的getname,isInterface等数据都来源于方法区。sun jdk中对应permanet generation

堆:默认物理内存的1/64。

本地方法栈:用于支持native方法的执行,存储了每个native方法调用的状态,sun jdk实现的中本地方法栈和jvm方法栈是同一个。

pc寄存器和jvm方法栈:每个线程会创建pc寄存器和jvm方法栈,pc寄存器可能占用cpu寄存器或操作系统内存,jvm方法栈占用操作系统内存。当jvm方法栈空间不足,会抛出stackoverflowerror,可通过-Xss配置。

二、内存分配

堆线程共享,因此堆分配内存空间时需要枷锁。

sun jdk为提升内存分配效率,为每个新建线程在eden space单独分配空间(thread local allocation buffer tlab),大小由jvm根据运行情况计算得到,可通过-XX:TLABWasteTargetPercent设置每个线程占eden space的百分比。

三、内存回收

通常采用收集器方式实现GC:

引用计数收集器:当计数器为零,说明对象已不再被使用,可回收。对循环调用不适合。

跟踪收集器:全局记录数据引用状态,基于一定条件触发(定时、空见不足),执行是从根集合扫描对象引用关系。

算法有:

复制:从根集合扫描存活对象,将其复制到新的未使用的空间中取。

标记-清除:从根集合扫描存活对象,对其进行标记。完毕后,扫描整个空间中未标记对象,进行回收。因直接回收不引用对象,会造成内存碎片。

标记-压缩:在标记-清除的基础上,将存活对象往左端空闲空间移动,并更新引用其对象的指针。

四、可用GC

1、串行GC(Serial GC)

根集合对象:当前运行线程栈上引用的对象、常量、静态变量、传到本地方法中还未被本地方法释放的对象引用加上下面的remember me。

remember me:针对旧生代引用新生代对象情况设置,当进行对象赋值是,若赋值为一个对象引用,则产生write barrier,然后检查需赋值的对象是否在旧生代及赋值的对象引用是否指向新生代,若满足条件,则在remember set做标记。sun jdk使用card table实现remember me。

2、并行回收GC(Parallel Scavenge)

3、并行GC(ParNew)

你可能感兴趣的:(jvm,GC)