美文网首页
JVM原理及回收机制

JVM原理及回收机制

作者: 笑_小小 | 来源:发表于2018-08-19 23:21 被阅读0次

    首先,JVM是什么?

    JAVA字节码是在JRE(java runtime environment)中运行,而JRE是由JavaAPI和JVM组成。

    JVM (Java Virtual Machine) 是JRE的核心组成,承担了其分析和执行Java字节码的工作,JVM是通过类加载器(Class Loader)加类Java应用,并通过Java API进行执行。

    引申: 类加载机制及双亲委托模型?

    Java类的生命周期:

    加载 --> 链接(验证 --> 准备 --> 解析 )--> 初始化 -->使用 --> 卸载 (细节自行体会)

    双亲委托机制:当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载。

    如下图:

    JVM内存管理及垃圾回收

    JVM内存组成结构:堆/栈/本地方法栈/方法区

    堆:所有new的对象都在此,堆的大小可以通过一些配置项来控制(-Xmx和-Xms)堆分为新生代,老年代。(具体可参看垃圾回收机制)

    栈:每个线程在执行方法时会在栈中申请栈帧,包括局部变量区和操作数栈,用来存放此方法调用过程中的临时变量,参数,结果等。

    本地方法栈:支持native方法的执行。

    方法区:存放了要加载的类信息,静态变量,final常量,属性,方法信息等。JVM用持久代来存放方法区,可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值。

    垃圾回收机制:

    哪些内存需要回收?

    未被引用的对象/作用域发生未捕获异常/程序在作用域正常执行完毕/程序执行System.exit()/程序发生意外终止(被杀进程等)

    什么时候触发GC?

    (1)当应用程序空闲时,即没有应用线程在运行时,GC会被调用。

    (2)Java堆内存不足时,GC会被调用。

    怎么判断对象是否可被回收?

    两种算法:

    引用计数

    给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。

    优点:简单,高效,现在的objective-c用的就是这种算法。

    缺点:很难处理循环引用,相互引用的两个对象则无法释放。

    可达性分析(根搜索)

    从GC Roots作为起点,向下搜索它们引用的对象,可以生成一棵引用树,树的节点视为可达对象,反之视为不可达。

    在Java中,可以作为GC Roots的对象包括下面几种:

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

    方法区中的类静态属性引用的对象。

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

    本地方法栈中JNI(Native方法)的引用对象

    回收算法有哪些?

    引用计数/标记-清除/复制/标记-整理

    JVM在不同的时代用的是不同的回收机制,新时代存活时间端,基于复制算法来进行回收,新生代采用空闲指针的方式来触发GC,当有新的对象需要分配内存时,检查空间是否足够,不够就触发GC。

    旧生代存活时间较长,较稳定,采用标记算法来进行回收,标记即找出存活的对象,然后再进行回收未被标记的对象。

    方法区的对象也能被回收,只是条件非常苛刻,需要同时满足以下三个条件:

    所有实例被回收/加载该类的ClassLoader被回收/Class对象无法通过任何途径访问(包括反射)

    JVM内存调优

    内存查看工具:JConsole和Java VisualVM

    调优目的:减少GC的频率和FULLGC的次数(占有CPU资源,影响吞吐量),尤其避免FULL GC。

    出现fullGC的几种情况:

    旧生代的空间不足/Pemanet Generation空间不足/System.gc()被显示调用

    JVM提供的GC策略设置方式:

    吞吐量优先-XX:GCTimeRatio=n/暂停时间优先-XX:MaxGCPauseRatio=n

    性能调优的原则:

    MinorGC回收原则: 每次minor GC 都要尽可能多的收集垃圾对象。以减少应用程序发生Full GC的频率。

    GC内存最大化原则:处理吞吐量和延迟问题时候,垃圾处理器能使用的内存越大,垃圾收集的效果越好,应用程序也会越来越流畅。

    GC调优3选2原则: 在性能属性里面,吞吐量、延迟、内存占用,我们只能选择其中两个进行调优,不可三者兼得。

    JVM常见配置

    堆设置

    -Xms:初始堆大小

    -Xmx:最大堆大小

    -XX:NewSize=n:设置年轻代大小

    -XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4

    -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5

    -XX:MaxPermSize=n:设置持久代大小

    收集器设置

    -XX:+UseSerialGC:设置串行收集器

    -XX:+UseParallelGC:设置并行收集器

    -XX:+UseParalledlOldGC:设置并行年老代收集器

    -XX:+UseConcMarkSweepGC:设置并发收集器

    垃圾回收统计信息

    -XX:+PrintGC

    -XX:+PrintGCDetails

    -XX:+PrintGCTimeStamps

    -Xloggc:filename

    并行收集器设置

    -XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。

    -XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间

    -XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

    并发收集器设置

    -XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。

    -XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

    相关文章

      网友评论

          本文标题:JVM原理及回收机制

          本文链接:https://www.haomeiwen.com/subject/ttvciftx.html