JVM

    科技2025-04-07  18

    文章目录

    一个对象创建的内存分配过程GC的基础知识1.什么是垃圾2.如何定位垃圾3.常见的垃圾回收算法4.JVM内存分代模型(用于分代垃圾回收算法)5.常见的垃圾回收器(垃圾收集器就是算法落地实现)6.垃圾收集器的发展7.JVM调优第一步,了解生产环境下的垃圾回收器组合

    一个对象创建的内存分配过程

    先尝试在栈上分配:经过逃逸分析和标量替换。 栈上创建对象的好处:栈内对象出栈之后,生命周期结束,不需要GC介入。 TLAB:thread local allocation buffer线程本地分配缓冲区,,调度线程的分配竞争。

    GC的基础知识

    1.什么是垃圾

    C语言申请内存:malloc free

    C++: new delete

    Java: new ?

    自动内存回收,编程上简单,系统不容易出错,手动释放内存,容易出两种类型的问题:

    忘记回收多次回收 垃圾指没有任何引用指向的一个对象或者多个对象(循环引用,垃圾堆)。 java的调优机制就集中在垃圾回收器的选择和参数设置上。

    2.如何定位垃圾

    引用计数(有缺陷:三个对象循环引用,但是没有栈引用,造成无法回收,内存泄漏。)根可达算法(root searching),根对象有引用的,不回收,其他都是垃圾。 根对象包括哪些?

    3.常见的垃圾回收算法

    标记清除(mark-sweep) - 位置不连续 产生碎片(两遍扫描)

    拷贝算法(copying) - 没有碎片,浪费空间

    标记压缩(mark-compact) - 没有碎片,效率偏低(两遍扫描,内存移动需要线程同步,影响效率)

    4.JVM内存分代模型(用于分代垃圾回收算法)

    部分垃圾回收器使用的模型

    新生代 + 老年代 + 永久代(1.7)/ 元数据区(1.8) Metaspace

    永久代 元数据 - Class永久代必须指定大小限制 ,元数据可以设置,也可以不设置,无上限(受限于物理内存,由操作系统管理)字符串常量 1.7 - 永久代,1.8 - 堆MethodArea逻辑概念 - 永久代、元数据

    新生代 = Eden + 2个suvivor区

    YGC回收之后,大多数的对象会被回收,活着的进入s0再次YGC,活着的对象eden + s0 -> s1再次YGC,eden + s1 -> s0年龄足够 -> 老年代 (15 CMS 6)s区装不下 -> 老年代

    老年代

    顽固分子老年代满了FGC Full GC(包括新生代和老年代全部gc一次)

    GC Tuning调优 (Generation 针对于分代模型)

    尽量减少FGC(效率很底,可能会系统停顿)MinorGC = YGCMajorGC = FGC

    5.常见的垃圾回收器(垃圾收集器就是算法落地实现)

    jvm的内存模型归gc回收器模型管

    Serial (stw:stop the world)年轻代 串行回收(小孩子扔线团和妈妈清理的场景。)

    PS 年轻代 并行回收(小孩子扔线团和长辈一起清理的场景。)

    ParNew 年轻代 配合CMS的并行回收(约等于PS,可以配合CMS用)

    SerialOld

    ParallelOld

    ConcurrentMarkSweep (CMS)老年代 并发的, 垃圾回收和应用程序同时运行,降低STW的时间(降低至200ms以内)

    G1(10ms)(jdk1.9以上默认)

    ZGC (1ms) PK C++

    Shenandoah

    Eplison(jdk11新加,不回收垃圾,jvm调试用)

    jvm1.8默认的垃圾回收:PS + ParallelOld

    6.垃圾收集器的发展

    垃圾回收器的演进与内存的大小发展有关系,内存越大与回收线程越多并不呈线性正相关,因为CPU性能(瓶颈)受限于线程切换(contextSwitch),影响gc清理。

    因此诞生了CMS(缺点:内存碎片化,浮动垃圾,此时若有大对象进来,调用serial old来清理腾地方,卡顿时间很久),jdk第一个并发执行的垃圾回收器,CMS的4个阶段:

    初始标记:标记根对象(STW)并发标记(mark sweep):并行;存在标记的重复利用(错标,严重),不用的没标记的问题(漏标,浮动垃圾)重新标记(STW),修改错标,又重新扫描一遍。并发清理。 怎么标记?怎么修改?并发标记算法(三色标记算法)错标cms的解决方案:A产生新的引用,重新变灰

    G1的产生

    告别物理分代,进行逻辑分代,分而治之。

    G1处理java文件的运行效率比其他的垃圾回收器的效率慢3%-4%(问题不大),因为存在**屏障(新建对象的时候),用于垃圾回收的标记。

    转:深入理解Java G1垃圾收集器

    7.JVM调优第一步,了解生产环境下的垃圾回收器组合

    JVM的命令行参数参考:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

    JVM参数分类

    标准: - 开头,所有的HotSpot都支持

    非标准:-X 开头,特定版本HotSpot支持特定命令

    不稳定:-XX 开头,下个版本可能取消

    -XX:+PrintCommandLineFlags

    -XX:+PrintFlagsFinal 最终参数值

    -XX:+PrintFlagsInitial 默认参数值

    Processed: 0.009, SQL: 8