java学习之:JVM学习与总结

一、JVM结构

1、jvm概述

Java Virtua Machine:java虚拟机,它是java语言跨平台的一个核心的东西。我们可以将它看作是一个虚拟的计算机,它负责将我们的class文件翻译成我们各个操作系统中真正能够读懂的可执行语言,确保字节码文件可以在不同的系统中正确运行。

2、jvm体系结构

如下图所示:jvm体系结构主要分为三大类:1、类加载器子系统,2、运行时数据区, 3、执行引擎
在这里插入图片描述

2.1 Class Loader SubSystem

类加载器子系统,处理java动态类加载功能,它是在运行时首次引用类的时候进行1、加载,2、连接3、初始化类文件。
加载由引导类加载器、扩展类加载器、应用程序类加载器帮助完成
连接过程分为:验证(验证字节码)、准备(为所有静态变量分配内存、默认值)、解析(用方法区的原始引用,代替所有符号内存引用)
初始化:所有静态变量分配原始值,并执行静态代码块

2.2 运行时数据区

方法区:存储所有类级别的数据,每个jvm只有一个方法区,它是一个线程共享资源
堆区:存储所有对象及其对应的实例,变量,数组,每个jvm只有一个堆区,它是一个线程共享资源
栈区:每个线程创建一个单独的运行时栈,所有局部变量在栈内存生成。
PC寄存器: 保存当前正在执行的指令
本地方法栈:保存本机的方法信息

3.2 执行引擎

JIT:及时编译器,通过热点探测来及时编译代码,起到一个提高编译效率的作用
GC:垃圾回收器,收集删除未被引用的对象。
本地方法接口:与本地方法库交互
本地方法库:执行引擎需要本机库的集合

二、JVM分代介绍

前面已经提到jvm中的堆内存主要是用于存放对象的实例,而这块区域的空间也是有限的,不可能无限制的存放对象,所以这块区域是我们垃圾回收机制的主要工作区域,回收那些没有被引用的对象,但是我们的垃圾回收机制如果频繁的对整块区域进行垃圾回收的话势必会影响我们的系统性能。所以,我们对这一块区域经行了划分,有些区域是可以频繁的回收对象,有些区域是达到某个阈值才会触发一次垃圾回收,如下图所示:
在这里插入图片描述
我们将JVM中的堆内存划分为:1、新生代,2、老年代,3、永久代(1.8以后已经将其移除),接下来我们来了解一下各个代的作用。

1、新生代

新生代可以分为:1、Eden,2、From Survivor ,3 、 To Survivor 三个区域,它们的空间配置比例默认是8:1:1。Survivor 这两个区域是用来存放周期较长的对象,并用于将对象转移到老年代的过度区域。因为在我们的实际开发中,大多数的对象的生命周期都不是很长,所以这种配置比例可以有效的利用空间。新生代是垃圾回收的主要地,在新生代中,常规的经行一次垃圾回收一般可收集70%~95%的空间。

1.1 Eden

这块区域其实就是java对象的伊甸园(大对象直接进入老年代),换句话说就是对象的出生地。当这块区域的空间没有足够的空间进行分配的时候,虚拟机就会发起一次MinorGC.

1.2 Survivor

From Survivor 和 To Survivor 被称为幸存区域,其实就是存活的对象,在上一次GC的时候,对象只存在与Eden 和 From Survivor 区域,To Survivor 这个区域是空的,下一次GC的时候,Eden中所有的存活的对象都会被复制到To Survivor这个区域,而在From Survivor这个区域任然存活的对象年龄阈值+1,当超过门限(默认15)变会被转移到老年代,未超过阈值的被转移到To Survivor。这个时候,From Survivor 和 To Survivor互相转换角色,这样就保证了每一次GC后, To Survivor这个区域是空的。

2、老年代

在这块区域中存活的对象周期相对较高,GC的周期也是相对较慢。

三、JVM垃圾回收算法

1 、引用计数(Reference Counting)

原理:对象有一个引用,计数+1,删除一个引用,计数-1,垃圾回收时,回收计数为0的对象。
缺陷:无法处理循环引用的对象。

2、复制(copying)

原理:将内存划分为两个相等的区域,每一次只使用一个区域(From Survivor 和 To Survivor就是使用的复制算法),垃圾回收时,遍历当前的区域,把正在被使用的对象复制到另外一个区域中去。
优点:此算法只处理正在被使用的对象,复制成本小,复制后可以对另一个区域经行内存整理,可以有效避免内存碎片。
缺点:需要两块内存空间

3、标记-清除(Mark Sweep)

原理:此算法分两个阶段:第一阶段,从引用根节点开始,标记所有被引用的对象;第二阶段,遍历整个堆,对未标记的对象经行清除。
缺点:会暂停整个应用,同时会产生内存碎片。

4、标记-整理(Mark-Compact)

原理:此算法结合了标记清除和复制算法的优点,同时也是分为两个阶段:1、从根节点开始标记所有被引用对象;2、遍历整个堆,清除未标记对象,将标记对象“压缩”到堆中的一块,按照顺序排放。
优点:避免了空间碎片,不需要像复制算法那样需要两个空间。

四、垃圾收集器

不同的代有不同的垃圾回收器,jvm中有七个不同的收集器,每个收集器都有其特有的功能和特点,合理的选择收集器是我们优化jvm的一个方向,如下图所示:
在这里插入图片描述

1、Serial

串行收集器,它是Hotspot运行在Client模式下的默认新生代收集器。它的特点就是只用了一个cpu的线程去完成GC工作,并且在垃圾回收的期间其它工作线程必须暂定,因此它有一个别名叫stop the world

2、ParNew

并行收集器,这种垃圾回收器其实是Serial的升级版本,其实就是多增加了几个线程来完成GC工作,这种垃圾收集器适合多核的环境下使用。ParNew也没有解决在垃圾回收时暂停其它工作线程的问题,只是说在多线程情况下,缩短了GC安全点的时间

3、Parallel Scaverage

这款并行收集器与ParNew类似,只是这一款垃圾收集器更加关注系统的吞吐量(系统吞吐量=运行用户代码时间/(运行用户代码时间+GC时间)),通过降低GC回收对象的时间,从而提高系统的性能。

4、CMS

Concurrent Mark Sweep 这款收集器是真正意义的并发收集器,它可以和新生代的Serial、ParNew配合工作。

5、Serial Old

这一块收集器是Serial的老年代版本,一样的是单线程收集器,它使用的是“标记-整理”算法。

6、Parallel Old

Parallel Old 是Parallel Scaverage 的老年代版本,使用多线程和“标记-整理”算法,这一款收集器只能和行省的的Parallel Scaverage配合使用。

7、G1

Garbage First 是一款面向服务器应用的收集器,主要目标用于配备多频CPU的服务器治理大内容。
G1与其他分代收集器不同,它将整个堆空间划分为多个大小相等的独立区域(Region),虽然还是保留有新生代和老年代的概念,但是新生代与老年代不再是物理隔离,它们是一部分region的集合。

五、JVM性能检测工具

1、jps

jdk自带的小工具,用于查看虚拟机线程
在这里插入图片描述

2、jstat

这款工具需要jps配合使用.用于查看虚拟机运行时信息。通过该工具可以实时查看堆不同分代的内存使用和GC时间的信息。
在这里插入图片描述

3、jvisualvm

这是一款图形化界面的性能工具,通过这款工具可以查看我们本地或者远程虚拟机的参数配置,CPU、堆内存、类、线程的信息。
在这里插入图片描述

六、JVM常见参数介绍

1、堆设置

-Xms:初始堆大小
-Xmx:最大堆大小 建议Xmx与-Xmx相同,避免每次垃圾回收完成后JVM重新分配内存
-Xmn:年轻代大小 (堆=年轻代+年老代+永久代 增大年轻代会减小年老代)建议堆*3/8
-Xss:每个线程的堆栈大小 (小应用 栈浅128k/ 大应用256k 对性能影响比较大,需要严格的测试)
-XX:NewSize=n:年轻代大小
-XX:NewRatio=n:年老代:年轻代比值
-XX:SurvivorRatio=n:年轻代中 Eden:SFrom:STO=n:1:1
-XX:PretenureSizeThreshold:直接晋升到老年代的对象大小
-XX:MaxTenuringThreshold=0:垃圾最大年龄.
设置0 年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.
如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活 时间,增加在年轻代即被回收的概率.
-XX:PermSize:永久代(perm gen)初始值。默认为物理内存的1/64。
-XX:MaxPermSize:持久代最大值。物理内存的1/4。

2、垃圾回收统计信息

-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintGCDateStamps — 打印GC操作的时间戳
-Xloggc:filename :把相关日志信息记录到文件以便分析。
-XX:PrintHeapAtGC :打印GC前后的详细堆栈信息

3、收集器设置

-XX:+UseSerialGC:串行收集器 虚拟机Client模式-Serial+Serial Old
-XX:+UseParallelGC:并行收集器 虚拟机server模式-Parallel Scavenge+Serial Old
-XX:+UseParNewGC:使用ParNew+SerialOld

-XX:+UseParalledlOldGC:并行年老代收集器 Parallel Scavenge+Parallel Old
-XX:+UseConcMarkSweepGC:并发收集器 ParNew+CMS+Serial Old(后备 CMS出现Concurrent Mode Failure失败)

4、并行收集器设置

-XX:ParallelGCThreads=n:并行收集器收集时使用的CPU数.并行收集线程数.
-XX:MaxGCPauseMillis=n:并行收集最大暂停时间 Parallel Scavenge收集器
-XX:GCTimeRatio=n:垃圾回收时间占程序运行时间的百分比.公式为1/(1+n) 默认99为1%的GC时间,使用Parallel Scavenge收集器时

5、并发收集器设置

-XX:+CMSIncrementalMode:为增量模式.适用于单CPU情况.
-XX:ParallelGCThreads=n:并发收集器年轻代收集方式为并行收集时,使用的CPU数.并行收集线程数.

6、其他:

-XX:-DisableExplicitGC — 让System.gc()不产生任何作用
-XX:PrintTenuringDistribution — 设置每次新生代GC后输出幸存者乐园中对象年龄的分布
-XX:InitialTenuringThreshold / -XX:MaxTenuringThreshold:设置老年代阀值的初始值和最大值
-XX:TargetSurvivorRatio:设置幸存区的目标使用率
-XX:+UseAdaptiveSizePolicy:动态调整java堆中各个区域的大小以及进入老年代的年龄
-XX:+HandlePromotionFailure:是否允许分配担保失败,即老年代的剩余空间不足以应付新生代的整个Eden和Survivor区的所有对象都存活的极端情况

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值