设为首页 加入收藏

TOP

JVM总结(二)
2023-07-25 21:41:17 】 浏览:72
Tags:JVM 总结
,jvm通过引用队列是否包含这个虚引用来了解这个对象是否将要被进行垃圾回收

3. 对象分配

对象在内存中如何分配

对象优先在Eden区中分配,当Eden区没有足够的空间时,会触发垃圾回收,把存活的对象移动到Survicor空间,如果Survivor空间也满了,则会把部分对象移动到老年代中,如果对象太大,是一个大对象,则这个对象会直接分配到老年代,不会发生GC

对象如何从年轻代进入老年代

  • 对象年龄够老,默认是15,可以通过XX:MaxTenuringThreshold设置,复制到老年代,同时年龄加1
  • 大对象会直接分配到老年代,大对象的定义和具体的JVM版本,堆大小,垃圾回收策略有关,一般为2K~128k,可以通过XX:pretenureSizeThreshold设置其大小

4. 垃圾收集器

JVM针对新生代和老年代分别提供了不同的垃圾收集器,新生代有Serial,ParNew,Parallel Scavenge,针对老年代提供的垃圾收集器有Serial Old,Parallel Old,CMS,还有针对不同区域的G1分区收集算法

常见的垃圾收集器

Serial垃圾收集器

Java虚拟机运行在Client模式下的新生代的默认垃圾收集器,基于复制算法实现,是一个单线程收集器,在进行垃圾收集时,必须暂停其他所有工作线程,直到垃圾收集结束,Serial收集器对于但CPU运行环境来说,没有线程交互开销,可以获得最高的单线程垃圾收集效率

ParNew垃圾收集器

Java虚拟机运行在Server模式下,新生代的默认垃圾收集器,基于复制算法实现,采用多线程模式工作,在进行垃圾收集时,必须暂停其他所有工作线程,直到垃圾收集结束,ParNew垃圾收集器默认开启与CPU同等数量的线程进行垃圾回收,可以通过-XX:ParallelGCThreads参数调节工作线程数

Parallel Scavenge垃圾收集器

Parallel Scavenge垃圾收集器是为提高新生代垃圾收集效率而设计的垃圾收集器,基于复制算法实现,采用多线程,在系统吞吐量上有很大的优化,,可以更高效的利用CPU完成垃圾回收任务,Parallel Scavenge提供了三个参数用于调节,控制垃圾回收的停顿时间及吞吐量,分别是:控制足最大垃圾收集停顿时间:-XX:MaxGCPauseMillis,控制吞吐量大小:-XX:GCTimeRation,控制是否开启自适应调节策略:UseAdaptiveSizePolicy

Serial Old垃圾收集器

Serial Old是JVM运行在Client模式下,老年代的默认垃圾收集器,Serial Old是Serial的老年代实现,同Serial一样采用单线程执行,不同的是Serial Old基于标记整理算法实现

Parallel Old垃圾收集器

Parallel Old垃圾收集器采用多线程并发进行垃圾回收,基于标记整理法实现,在设计上优先考虑系统吞吐量,其次考虑停顿时间等因素

CMS垃圾收集器

CMS垃圾收集器是为老年代设计的垃圾收集器,其主要目的是达到最短时间的垃圾回收停顿时间,基于线程的标记清除算法实现

CMS的垃圾回收过程

  • 初始标记:只标记GC Roots直接关联的对象,速度很快,需要暂停所有工作线程
  • 并发标记:和用户一起工作,执行GC Roots跟踪标记过程,不需要暂停工作线程
  • 重新标记:为了确保并发标记的正确性,重新标记已经标记的对象,需要暂停工作线程
  • 并发清除:和用户线程一起工作,执行清除GC Roots不可达对象的任务,不需要暂停工作线程

G1垃圾收集器

G1垃圾收集器是为了避免全区域垃圾收集引起的系统停顿,将堆内存划分大小固定的几个独立区域,独立使用这些区域跟踪垃圾收集进度,同时在维护一个优先级列表,根据系统允许的最长垃圾收集时间,优先回收垃圾最多的区域,相对于CMD垃圾收集器,G1垃圾收集器不产生内存碎片,可以精确的控制停顿时间,在不牺牲吞吐量的前提下实现停顿垃圾回收

G1垃圾回收器参数

  • -XX:MaxGCPauseMillis:暂停毫秒级,默认200毫秒
  • -XX:G1HeapRegionSize:区域大小,默认最多2048块,每块的大小需要为2的幂次方,最大为32M
  • -XX:G1NewSizePercent:新生代的最低百分比,默认5%
  • -XX:G1MaxNewSizePercent:新生代的最大百分比,默认60%

5. 类加载器

类加载器负责将class文件加载到java虚拟机中,并为之创建一个Class对象

类加载器的流程

  • 加载:将class文件加载到内存中,将静态数据结构转化成方法区中运行时的数据结构,在堆中生成一个代表这个类的对象,作为数据访问的入口
  • 验证:确保加载的类符合JVM规范和安全,保证被效验类的方法在运行时不会做出危害虚拟机的事件,做一个安全检查
  • 准备:为static变量在方法区中分配内存空间,设置变量的初始值,注意只设置静态变量,不包括实例变量,实例变量在对象初始化时赋值
  • 解析:虚拟机将常量池内的符号引用替换为直接引用的过程,符号引用中的符号可以是任何形式的字面量,只要能无歧义的定位到目标即可,直接引用是可以直接指向目标的指针,相对偏移量或者间接定位到目标的句柄
  • 初始化:初始化类变量和其他资源
  • 使用
  • 卸载:GCh将对象从内存中卸载

常用的类加载器

  • 启动类加载器(Bootstrap ClassLoader):虚拟机内置类加载器,加载java核心类库,如JAVA_HOME/jre/lib/rt.jar,resources.jar,sun.boot.class.path,使用C+/C++实现,他没有父类加载器,是扩展类加载器和应用程序加载器的父类加载器
  • 扩展类加载器(Extension classLoader):由java语言编写,从系统属性java.ext.dirs目录中或者JDK安装目录JRE/lib/ext加载类库
  • 应用程序类加载器(Application ClassLoader):应用程序类加载器,负责加载用户类路径上所指定的类,我们程序中默认的类加载器,可以通过ClassLoader#getSystemClassLoader()获取并操作这个加载器

双亲委派机制

双亲委派机制是当一个类加载器需要加载一个字节码文件时,首先会把这个任务委托给他的上级类加载器,上级类加载器又交给他的上级,以此递归,直到上级类加载器不能加载该字节码文件,然后再自己去加载这个字节码文件,如果自己也无法加载则抛出ClassNotFoundException异常,这样做的好处是防止一个字节码文件多次加载,保证了数据的安全性,即使重复加载了也不会是同一个class对象

6. JVM调优

在调优之前要先明确是否需要使用JVM调优,因为大多数Java应用是不需要调优的,大多数导致GC问题的原因是代码层面的问题,比如创建的对象数量过多,使用了大量的全局变量和大对象

需要调优的场景

  • Heap内存(老年代)持续上涨,达到设置的最大内存值
  • Full GC次数频繁
  • GC停顿时间过长
  • 应用出现OutOfMemory等内存异常
  • 系统吞吐量不高

调优步骤

  • 分析GC日志和Demp文件,判断是否需要优化,确定瓶颈问题点
  • 确定JVM调
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇一个更适合Java初学者的轻量级开.. 下一篇面试官:怎么删除 HashMap 中的元..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目