JVM内存管理

(仅用作自己复习)

JVM知识点

1.JVM的位置

在操作系统之上,可以理解为一个软件

2.JVM的体系结构

JVM内存结构往往指的就是JVM定义的“运行时数据区域“

程序计数器:就是一个指针,指向方法区中的方法字节码。

程序计数器就是用于记录各个线程执行的字节码的地址。(分支、循环、跳转、异常、线程恢复等都依赖于计数器)

虚拟机栈:每个线程创建的时候都会创建一个”虚拟机栈“,每次方法调用都会创建一个”栈帧“。每个”栈帧”会包含几块内容:局部变量表、操作数栈、动态链接和返回地址。

本地方法栈:本地方法栈跟虚拟机栈的功能类似,虚拟机用于管理JAVA函数的调用,而本地方法栈则用于管理本地方法的调用。这里的本地方法指的是“非java方法”,一般本地方法是使用c语言实现的。

方法区:在hotspot虚拟机,就会常常提到“永久代”这个词。在jdk8前,用“永久代”实现了方法区。在jdk8中,用"元空间"来替代了“永久代”作为“方法区”的实现。“元空间”:存储不在虚拟机中,而是使用本地内存,JVM不会再出现方法区的内存溢出)方法区主要用来存放已被虚拟机加载的“类相关信息”:包括类信息、常量池。类信息包括了类的版本、字段、方法、接口和父类等信息。常量池又可以分“静态常量池”和“运行时常量池”。静态常量池主要存储的是「字⾯量」以及「符号引⽤」等信息,静态常量池也包括了我们说的「字符串常 量池」。运⾏时常量池」存储的是「类加载」时⽣成的「直接引⽤」等信息。从jdk7之后,将常量池转移到了堆内存中进行存储。(物理分区属于堆)

堆:线程共享的区域,几乎类的实例和数组分配的内存都来自于它。被分为“新生代”和“老年代”。

3.Java的垃圾回收机制

3.1如何判断对象什么时候会被回收?

判断对象是否存活一般有两种方式:

  • 引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计 数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。
  • 可达性分析(Reachability Analysis):从GC Roots开始向下搜索,搜索所走过的路径称为引 用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对 象。

什么是GC Roots?

3.2垃圾回收算法

GC最基础的算法有三种: 标记 -清除算法、复制算法、标记-压缩算法,我们常用的垃圾回收器一般 都采用分代收集算法。

  • 标记-清除算法
  • 标记-复制算法
  • 标记-清除-压缩算法
  • 分代收集算法,“分代收集”(Generational Collection)算法,把Java堆分为新生代和老年代, 这样就可以根据各个年代的特点采用最适当的收集算法。

3.3垃圾收集器

  • 新生代收集器:Serial、 ParNew 、 Parallel Scavenge
  • 老年代收集器: CMS 、Serial Old、Parallel Old(Serial是单线程的,Parallel是多线程)
  • 整堆收集器: G1 , ZGC (因为不涉年代不在图中)

具体垃圾回收器:(可以发现的是,「年轻代」的垃圾收集器使⽤的都是「标记复制算法」 ,所以在「堆内存」划分中,将年轻代划分出Survivor区(Survivor From 和Survivor To),⽬的就是为了 有⼀块完整的内存空间供垃圾回收器进⾏拷⻉(移动) )

  • Serial收集器(复制算法): 新生代单线程收集器,标记和清理都是单线程,优点是简单高效;
  • ParNew收集器 (复制算法): 新生代收并行集器,实际上是Serial收集器的多线程版本,在多核 CPU环境下有着比Serial更好的表现;
  • Parallel Scavenge收集器 (复制算法): 新生代并行收集器,追求高吞吐量,高效利用 CPU。吞 吐量 = 用户线程时间/(用户线程时间+GC线程时间),高吞吐量可以高效率的利用CPU时间,尽 快完成程序的运算任务,适合后台应用等对交互相应要求不高的场景;(吞吐量优先收集器)
  • Serial Old收集器 (标记-整理算法): 老年代单线程收集器,Serial收集器的老年代版本;
  • Parallel Old收集器 (标记-整理算法): 老年代并行收集器,吞吐量优先,Parallel Scavenge收集器的老年代版本;
  • CMS(Concurrent Mark Sweep)收集器(标记-清除算法): 老年代并行收集器,以获取最短回 收停顿时间为目标的收集器,具有高并发、低停顿的特点,追求最短GC回收停顿时间。
  • G1(Garbage First)收集器 (标记-整理算法): Java堆并行收集器,G1收集器是JDK1.7提供的一 个新收集器,G1收集器基于“标记-整理”算法实现,也就是说不会产生内存碎片。此外,G1收 集器不同于之前的收集器的一个重要特点是:G1回收的范围是整个Java堆(包括新生代,老年 代),而前六种收集器回收的范围仅限于新生代或老年代。
  • ZGC (Z Garbage Collector)是一款由Oracle公司研发的,以低延迟为首要目标的一款垃圾收 集器。它是基于动态Region内存布局,(暂时)不设年龄分代,使用了读屏障、染色指针和内 存多重映射等技术来实现可并发的标记-整理算法的收集器。在 JDK 11 新加入,还在实验阶 段,主要特点是:回收TB级内存(最大4T),停顿时间不超过10ms。优点:低停顿,高吞吐 量, ZGC 收集过程中额外耗费的内存小。缺点:浮动垃圾 目前使用的非常少,真正普及还是需要写时间的。

3.4CMS垃圾回收器(并发标记低停顿)(回收老年代)(已被移除最新的JDK)

3.4.1CMS设计目标

为了避免老年代GC出现长时间的卡顿。用户线程与回收线程并行。

3.4.2 CMS步骤

初始标记、并发标记、并发预处理、重新标记和并发清除。初始标记以及重新标记这两个阶段会Stop The World

3.4.3 CMS弊端

会产⽣内存碎⽚&&需要空间预留:停顿时间是不可预知的

3.5 G1垃圾回收器(Java9以上默认的垃圾回收器)

可以设定最大STW停顿时间

G1的内存布局:

 无需回收整个堆,而是选择一个Collection Set(CS)

两种GC:

  • minor GC
  • Mixed GC

问题:跨代引用(RSet)

空间换时间,当更新指针时:

  • 标记Card为Dirty
  • 将Card存入Dirty Card Queue
  • 白、绿、黄、红四个颜色

G1垃圾回收器在物理上不再分代,而是分区。逻辑上划分代。一般默认划分成2048个region。刚开始5%的region划分为新生代,新生代中eden区和to survivor,from survivor划分比例依旧是8:1:1.当新生代扩充到60%时,挑选那些最有价值的region进行回收,按照复制算法;当老年代扩充到45%时,触发混合回收,新生代、老年代和大对象都会进行回收。

G1垃圾回收器过程:

  1. 初始标记:会产生STW

  2. 并发标记(可能发生引用对象的变化,通过快照方式存储)

  3. 最终标记

  4. 混合回收(为了保证设置的STW,选择最具回收性价比的region进行回收)

3.6JVM调优

一般系统优化思路:

3.6.1 JVM性能调优参数

        调优JVM其实就是在理解JVM内存结构以及各种垃圾收集器的前提下,结合自己的现有业务来调整参数,使业务能正常运行。一般调优JVM可参考的指标有“吞吐量”、“停顿时间”和|垃圾回收频率”。

1.内存区域大小及相关策略

设定堆内存大小 -Xmx:堆内存最大限制。

设定新生代大小。 新生代不宜太小,否则会有大量对象涌入老年代

  • -XX:NewSize:新生代大小
  • -XX:NewRatio 新生代和老生代占比
  • -XX:SurvivorRatio:伊甸园空间和幸存者空间的占比

eg:IO密集型的可以稍微把“年轻代”空间加大些,因为大多数对象都是在年轻代就会灭亡。内存计算密集型的可以稍微把“老年代”空间加大些,对象存活的时间更久一些。

2.垃圾回收器

设定垃圾回收器 年轻代用 -XX:+UseParNewGC 年老代用-XX:+UseConcMarkSweepGC

3.6.2 JVM调优工具

常用调优工具分为两类,jdk自带监控工具:jconsole和jvisualvm,第三方有:MAT(Memory Analyzer Tool)、GChisto。

  • jconsole,Java Monitoring and Management Console是从java5开始,在JDK中自带的java监 控和管理控制台,用于对JVM中内存,线程和类等的监控
  • jvisualvm,jdk自带全能工具,可以分析内存快照、线程快照;监控内存变化、GC变化等。
  • MAT,Memory Analyzer Tool,一个基于Eclipse的内存分析工具,是一个快速、功能丰富的
  • Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗 GChisto,一款专业分析gc日志的工具

3.6.3JVM调优命令

  1. 通过jps命令查看java进程,统计类相关的信息(类加载、编译相关信息统计,各个内存区域GC概况和统计)。这个命令很常用于看GC的情况。
  2. 通过jstat命令查看Java进程「统计类」相关的信息(类加载、编译相关信息统计,各个内存区域GC概 况和统计)。这个命令很常⽤于看GC的情况
  3. 通过jinfo命令来查看和调整Java进程的「运⾏参数」
  4. 通过jmap命令来查看Java进程的「内存信息」。这个命令很常⽤于把JVM内存信息dump到⽂件,然后 再⽤MAT( Memory Analyzer tool 内存解析⼯具)把⽂件进⾏分析
  5. 通过jstack命令来查看JVM「线程信息」。这个命令⽤常⽤语排查死锁相关的问题

 3.6.4JVM的JIT优化技术

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值