一、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:
引用计数收集器:当计数器为零,说明对象已不再被使用,可回收。对循环调用不适合。
跟踪收集器:全局记录数据引用状态,基于一定条件触发(定时、空见不足),执行是从根集合扫描对象引用关系。
算法有:
复制:从根集合扫描存活对象,将其复制到新的未使用的空间中取。
标记-清除:从根集合扫描存活对象,对其进行标记。完毕后,扫描整个空间中未标记对象,进行回收。因直接回收不引用对象,会造成内存碎片。
标记-压缩:在标记-清除的基础上,将存活对象往左端空闲空间移动,并更新引用其对象的指针。
原文:http://dlyss.blog.51cto.com/3257105/1606744