jvm垃圾回收浅谈

jvm垃圾的概念

  1. 在内存中有一个对象,但没有任何引用指向他。
  2. 多对象之间互相循环引用,但没有其他引用指向这些对象

如何找到垃圾

  1. reference count (引用计数)

对引用的次数进行计数,有几次引用就记为几,当引用次数为0时,记为垃圾。

问题:循环引用,但是并没有栈空间内其他引用指向这个循环引用中的对象,循环引用中的引用计数都为1,但其实他们都属于垃圾,就会产生内存泄漏。

  1. root searching(根搜索算法/根可达算法)

根对象指的是当前线程中的正在使用的局部变量、class中引进的静态变量、常量池和jni指针引进的变量,也叫GC
roots,通过根找不到的全是垃圾,只要通过根对象引用的,或者引用出来再引用的,都不是垃圾。

常见的垃圾回收算法

  1. mark-sweep 标记清除

找到垃圾,标记为非垃圾区域

缺点:空闲的位置不连续,产生碎片

  1. copying 拷贝

将整个区域分为两半,把存活对象/或者说叫已占用内存,统一copy至其中的一块区域,后期再分配区域时,分配已占用的那半部分区域,需要回收的时候,再重复将存活对象copy至另一半区域,继续相同操作。

优势:没有碎片且效率较高。

问题:浪费空间,需要准备双份内存(有一半的空间总是没有在使用)。

  1. mark-compact 标记压缩

在回收的同时,将存活对象放到要回收的区域,对区域进行压缩整理。把已使用的区域挨个排列,放到一起,未使用的区域放到一起。

优势:不浪费空间、内存连续

缺点:效率相对比较低(找到垃圾与拷贝的效率是一样的,但是对压缩来说相对复杂,因为任何一块内存在移动时,如果是多线程,需要进行线程同步,如果是单线程,那单线程本来就效率比较低)

jvm分代算法

把jvm中的空间分为不同的代/区域

jdk1.8:主要分为两代-新生代、老年代

jdk1.7:还有一部分叫永久代(jdk 1.8的时候叫元数据区)

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

  1. 部分垃圾回收期使用的模型

  2. 新生代 + 老年代 + 永久代(1.7) / 元数据区(1.8,受限于操作系统,不受堆管理)
    2.1). 永久代 元数据区 都是装Class对象的

    2.2). 永久代必须指定大小限制,元数据区可以设定,也可以不设定,无上限(受限于物理内存)

    2.3). 字符串常量,1.7是存在永久代的,1.8之后存在堆里

堆内存逻辑分区

主要分为新生代和老年代,新生代与老年代比例为一比三。

新生代分为 eden(伊甸)区,和两个survivor区,比例为 8:1:1。

对象产生过程:当new一个对象出来,一般会去eden区分配内存,但如果new对象内存过大,会直接进入
老年代。

新生代垃圾回收特点:YoungGC回收之后,大多数的对象会被回收。

  • 新生代使用的是copy拷贝算法,伊甸区的对象进行回收时,继续使用的对象进入survivor
    0区,伊甸区整个清空,可以全部继续使用(第一次YGC)。

  • 第二次YGC时,将伊甸区和survivor 0区的所有对象全部放入survivor 1区,伊甸区与survivor 0区,全部清空。

  • 再次YGC时,伊甸区的新对象和survivor 1区的对象,放入survivor 0区,清空伊甸区和survivor
    1区(copy算法的来回倒腾…)

当一个对象年龄够大时(来回倒腾就是不被清空,根据使用的垃圾回收期不同,具体次数也不同),将他放入老年代。

当伊甸区回收时,继续使用的对象太多,survivor区存放不下时,直接进入老年代。

老年代满了 -> 会触发一次FGC(Full GC)

GC调优 - GC Tuning:尽量减少FGC(Young GC + Old GC),因为FGC的算法是压缩算法,效率很慢

常见的垃圾回收器

serial、parnew、paraller Scavenge -> 新生代

CMS、SerialOldParallel Old -> 老年代
  1. Serial:a stop-the-world,copying collector which uses a single GC thread

系统运行中,触发GC,停掉所有线程,垃圾回收线程占用,回收之后,程序继续运行,再次触发时,相同操作。

  1. Paraller Scavaenge:

并行回收,多线程进行,效率较高

  1. ParNew

配合CMS并行回收

  1. Serial Old、Paraller Old

就是把Serial和paraller Scavenge的算法放进老年代运行

  1. ConcurrentMarkSweep

CMS 老年代 一个很复杂的算法,可以在垃圾回收过程中使程序依然继续运行

以上常见的六种垃圾回收器
serial、parnew、paraller Scavenge、CMS、SerialOld、Parallel Old
都是分代模型

后期出现了一些新的很好的垃圾回收器,例如G1、ZGC、Shenandoah、Eplison,这四种都是分区模型。

现在主要针对的调优方案主要是针对SerialParaller ScavaengeSerial OldParaller Old

jdk1.8默认的垃圾回收器是Paraller Scavaenge + Paraller Old

jvm常见命令

java - : 稳定命令

例如,java -version

java -X 开头,非标准

例如,-Xms 最小堆内存、-Xmx最大堆内存

java -XX 不稳定命令

查看具体内容的生效值/最终参数值 java -XX:+PrintFlagsFinal

查看具体内容的默认值 java -XX:PrintFlagsInitial

查看启动时的命令行参数 java -XX:PrintCommandLineFlags

例如,java -XX:UseG1GC,表示使用G1垃圾回收器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘水水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值