JVM内存基本理解
声明:本文内容仅作为本人方便记忆和查看所用。
JVM有五块内存空间:
1、method area:用于存储已被加载的类信息、常量、静态变量、即时编译后的代码等数据。
注:在JDK8中,Method Area(方法区)即PermGen(永久代)已经废弃,取而代之的是Metaspace(元空间);Metaspace的性质与Method Area基本类似,他们的本质区别是Metaspace不在虚拟机中,而是使用本地内存,理论上取决于32位/64位系统可虚拟的内存大。
2、heap:一般存放对象实例。
3、native method stack:作用和VM stack类似。
4、program counter register:当前线程执行字节码文件行号指示器,是唯一没有OutOfMemoryError的区域。
5、vm stack:每个方法在执行的时候都会创建一个栈帧,用于存放局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用到结束对应着stacks中入栈到出栈的过程。
其中1和2为线程共享数据区,其他为线程隔离数据区。
虚拟机创建对象:
1、heap中内存规整,则使用bump the pointer(指针碰撞);一般这种方式下GC为Serial、Palnew等带有compact过程。
2、heap中内存不规整,则必须维护一张表记录哪些内存可用,在分配的时候找到一块足够大的内存,并且更新该表,这种方式称为free list(空闲列表);一般这种方式下GC为CMS这种基于Mark-Sweep。
heap是否规整取决于GC方式是否带compact功能。
修改指针线程安全问题解决:
1、对分配内存空间时做同步处理,实际上虚拟机采用CAS配上失败重试的方法保证更新操作的原子性。
2、把内存分配的操作按照线程划分的不同的空间中,即每个线程在heap中预先分配一小块内存,称为本地线程分配缓冲,内存分配完之后需要将该内存初始化为零值,然后虚拟机对对象进行必要的设置。
GC:
young generation(minor GC):大部分对象在创建之后很快就会变得不可达。包含eden和survivor区。
old generation(major GC or full GC):对象没有不可达,从新生代存活下来,被复制到老年代。
card table:用来表示老年代某一区域中的所有对象是否持有对新生代对象的引用。这样新生代在GC的时候不需要花大量时间扫描所有老年代对象来确定对象的引用关系。
GC方式:
Serial GC:单线程收集器;Serial old是针对老年代的收集器
Parnew GC:Serial 新生代的多线程实现
Parallel :采用复制算法的多线程新生代收集器,主要关注目标是吞吐量
Parallel old(Parallel Compacting GC (JDK1.6后)):使用多线程和标记整理算法的老年代收集器
Concurrent Mark & Sweep GC(CMS):应用广泛,以获取最短停顿时间为目的;以标记清除算法为基础,会产生大量的空间碎片;为解决这个问题,默认提供-XX:+UseCMSCompactAtFullCollection收集开关参数(默认开启),用于在full GC完开启内存碎片的整理过程;还提供另外一个参数-XX:CMSFullGCsBeforeCompaction用于设置执行多少次不压缩full GC后跟着来一次带压缩的(默认次数为0)
GC ROOTS:
虚拟机栈中的引用对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
Native的引用对象
GC 算法:
标记清除:问题是容易产生大量的空间碎片,提前触发full GC
标记整理:老年代算法;先标记,再压缩,后清除
复制算法:新生代算法
增量算法:垃圾收集线程和应用程序线程交替运行;优点:减少系统停顿时间;缺点:因为线程切换和上下文转换的消耗,使得垃圾回收总成本上升,造成系统吞吐量下降。