java内存理解

1.JVM虚拟机内存组成介绍

  a)JVM内存划分为堆内存和非堆内存,堆内存分为年轻代(YoungGen)、老年代(OldGen),非堆内存就有一个永久代(PermGen)

  b)年轻代分为生成区(Eden)和生存区(Survivor),Survivor有FromSpace和ToSpace组成。Eden区占大容量,Survivor两个区占小容量,默认比例8:1:1

  c)堆内存用来存放的是对象,垃圾收集器就是收集这些对象,然后根据GC算法回收

  d)非堆内存永久代方法区(存储程序运行长时期存活的对象),比如类的元数据、方法、常量、属性等。

  

   jdk1.8版本废弃了永久代,使用元空间(MetaSpace),元空间与永久代类似,都是方法区实现,最大的区别是元空间不在JVM中,而是使用本地内存

2.jdk1.8为什么移除永久代

  a)字符串存在永久代容易出现性能问题和内存移除

  b)客户忽而方法的信息等比较难确定定大小,因此对于永久代(PermGen)的大小指定比较困难,太小容易出现永久代溢出,太大容易导致老年代溢出

  c)永久代会GC带来不必要的复杂度,并且回收率偏低

  d)Oracle可能将HotSpot与JRockit和二位一

3.新生代介绍

  新生成的对象首先放到Ede区,当Eden空间满了,触发MinorGC,存活下来的对象移动到Survivor0区,Survivor0满了触发MinorGC,Survivor0区存活对象移动到Survivor1区,保证一段时间内有一个Survivor区为空。经过多次MinorGC仍存活的对象移到OldGen。

  OldGen存储长期存活的对象,占满时触发MajorGC=FullGC,GC期间会停止所有线程等待GC完成

4.标记算法

  引用计数器算法:对象添加一个引用计数器,每当有一个地方引用它时就加一,引用失效减1,计数器为0的对象使不可被使用的,实现简单,效率高但无法解决循环引用的问题

  可达性分析计算方法:(Java使用)通过一系列称为GCRoots的对象作为起始点,从这些起始点向下搜索,搜索走过的路径称为引用链,当一个对象到GCRoots没有使用任何引用链时,说明该对象不可用

    java中的GCRoots:

      ①虚拟机栈(栈帧中的本地变量表)中引用的对象

      ②方法区中静态变量引用的对象

      ③方法区中常量引用的对象

      ④本地方法栈中(级一般说的Native方法)中JNI引用的对象

    优点:更加精准和严谨,可以分析出循环数据结构相互引用的情况

    缺点:实现复杂需要分析大量数据,消耗大量时间、分析过程需要GC停顿(引用关系不能发生变化),即停顿所有java执行线程(“Stop The World”, 是垃圾回收重点关注问题)

5.如何确认一个对象死亡

  宣告一个对象死亡,至少要经历两次标记

  第一次标记:如果对象进行可达性分析算法之后没发现与GCRoots相连的引用链,那么他将会第一次标记并且进行一次筛选。对象如果没有必要执行finalize方法(对象没有覆盖finalize方法或者finalize方法已经被JVM执行过),则判定为可回收对象。如果对象有必要执行finalize对象,则被放入F_Queue队列中,稍后在JVM自动建立低优先级的Finalize线程(可能多个线程)中触发方法;

  第二次标记:GC对F_Queue队列中的对象进行二次标记。如果对象在finalize方法中重新与引用链上的任何一个对象建立了关联,那么第二次标记是则会将他移除“即将回收”集合。如果此时对象还没成功脱逃,那么只能被回收了。

  finalize方法:是Object类的一个方法,一个对象的finalize方法中只会被系统自动调用一次,经过finalize方法逃脱死亡的对象。第二次不会再调用。tip:不建议使用,不可控

6.垃圾回收复制标记整理算法

  标记-清除算法(Mark-Sweep):分为标记和清除两个部分,首先标记处所有需要回收的对象,标记结束后统一回收所有标记的对象。标记清除两个过程效率都不高,清除后产生大量不连续的内存碎片,在之后需要分配大对象时找不到足够连续的内存触发另一次垃圾收集动作

  复制算法(Copying):将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当这一块的内存使用完了,就将还存活着的对象复制到另一块上面,然后把已使用过的内存空间一次清理掉。实现简单运行高效,但是需要消耗一半内存。(年轻代使用这种收集算法,IBM研究表明,98%的对象‘朝生夕灭’,所以不需要1:1划分内存空间。HotSpot默认 Eden:Survivor0:Survivor1=8:1:1)

  标记整理算法(Mark-Compact):标记过程与标记清除算法一致,但不是直接对可回收对象进行清理而是让所有存活的对象都向一端移动,然后清理掉边界以外的内存(老年代使用)

  分代收集算法(GenerationalCollection):根据各个年代的特点采用最适当的收集算法,在新生代中,每次垃圾收集有大批对象死去只有少量存活,选择复制算法。老年代中对象存活率高、没有额外空间进行担保使用标记清理或标记整理算法进行回收

7.垃圾回收器介绍

  垃圾回收器是垃圾回收算法的实现。以下罗列了HotSpot VM中的垃圾回收器以及适用场景

  

  jdk8以前,默认的垃圾回收器是Parallel Scavenge和Parallel Old

  jdk9开始默认垃圾回收器是G1

8.JVM常用参数

  详情

原文地址:https://www.cnblogs.com/dan2/p/13713112.html