总结篇(17)---JVM(java虚拟机) (4)垃圾回收

本文详细介绍了JVM垃圾回收的基本概念,包括Minor GC、Major GC和Full GC的区别,以及年轻代(Young Generation)和年老代(Old Generation)的划分原理。同时,深入探讨了Eden区、Survivor Spaces和Old Generation等内存区域的具体作用。

JVM垃圾回收

  • 垃圾回收就是回收那些不再使用的对象,即释放它们占用的内存。垃圾收集器跟踪所有正在使用的对象,并把其余部分当做垃圾。

    
一、JVM垃圾回收中的基本概念


概念解释说明
Minor  GC小型GC新生代GC,即发生在新生代的垃圾回收动作
Major  GC大型GC老年代GC,指发生在老年代的GC。CMS收集器中,当老年代满时会触发 Major GC。除了CMS收集器,其他都存在都不存在只针对年老代的收集
Full  GC完全GC对整个堆(新生代、年老代)和方法区进行垃圾收集


 

二、常见堆分类介绍


  • 研究发现,程序中的大多数可回收的内存可归为两类:

        (1)大部分对象很快就不再使用。
        (2)还有一部分对象不会立即无用,但也不会持续(太)长时间。


基于这一假设,VM中的内存被分为年轻代(Young Generation)年老代(Old Generation)。年老代有时候也称为年老区(Tenured)。
拆分成这样两个可清理的单独区域,允许采用不同的算法来大幅提高GC的性能。但这种方法也是有问题的,比如在不同分代中的对象可能会互相引用,在收集某一个分代时就会成为“事实上的”GC root。

三、堆内存池中的内存池划分。(注:不同的GC算法在实现细节上可能会有所不同)


(1)Eden(伊甸园、新生代,在年轻代中(Young Generation)):Eden是内存中的一个区域,用来分配新创建的对象。

        通常我们会有多个线程创建多个对象,所以Eden区被划分为多个线程本地分配缓冲区(TLAB)。
        通过这种缓冲区划分,大部分对象直接由JVM在对应线程的TLAB中分配,避免与其他线程的同步操作。

        如果TLAB中没有足够的内存空间,就会在共享Eden区(Shared Eden space)之中分配。如果共享Eden区也没有足够的空间,就会触发一次年轻代GC来释放空间。
        如果GC之后Eden区依然没有足够的空闲内存区域,则对象就会被分配到老年代空间(Old Generation)。

(2)Survivor Spaces(存活区,在年轻代中(Young Generation)):年轻代中所有存活对象都会被复制到“to”存活区,"to"区有对象,“from”区没有对象。
        任意时刻总有一个存活区是空的,存活的对象会在两个存活区之间复制,复制到另一个存活区之后,原本的存活区就会被清空。直到某些对象的存活时间达到一定的阈值,就会迁移到年老代。


(3)Old Generation(老年代,也称为Tenured):年老代中的对象大部分都是存活的,年老代GC发生的频率比年轻代小很多,采用移动对象的方式来实现最小化内存碎片。

(4)PermGen(永久代):在Java 8之前有一个特殊的空间,被称为永生代。这是存储元数据(metadata)的地方,比如class信息。

        实际上这块区域给java开发者造成了很多麻烦,因为很难去计算这块区域到底占用了多少内存空间。预测失败的结果就是导致产生永生代内存溢出。

(5)元数据区(Metaspace):既然计算元数据区所需的空间那么复杂,java8直接删除了永生代,改用Metaspace。此后,java中很多杂七杂八的东西都放置到普通的堆内存中。

        元数据区位于本地内存(native memory),不再影响到普通的java对象。
        默认情况下,Metaspace的大小只受限于java进程中可用的本地内存。
        这样程序就不再因为多加载了几个类/JAR包就导致永生代内存溢出。
        但如果Metaspace失控,则可能会导致很严重的内存交换(swapping),导致本地内存分配失败,可通过限制Metaspace大小的方式处理。

备注:

1)发生fullGC怎么排查

        1-1)确认Full GC:查看 GC 日志
        在 JVM 启动参数中启用 GC 日志,直接观察 Full GC 的发生频率和耗时:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/path/to/gc.log

        日志中的 Full GC 关键字标记了 Full GC 事件,例如:

[Full GC (Ergonomics) ... [PSOldGen: 1024000K->1023999K(1048576K)] ... , secs]

        关注 Full GC 前后的老年代内存变化(如 PSOldGen)、耗时(secs)和触发原因(如 ErgonomicsSystem.gc())。

        2)分析 Full GC 的可能原因:定位内存泄漏、配置问题或代码缺陷。

        使用Arthas:动态跟踪 JVM 状态,执行命令如 heapdumpvmtool 快速诊断问题。

        2-1)内存泄漏(Memory Leak)

  • 现象:老年代内存使用率持续增长,Full GC 后内存回收不足,最终导致 OutOfMemoryError

        2-2)系统配置不合理

  • 现象:堆内存分配过小或 Survivor 区比例不当,导致对象过早晋升到老年代。

        2-3)大对象分配(Large Object Allocation)

  • 现象:大对象(如大数组)直接进入老年代,导致老年代快速填满。

        3)优化调整:调整 JVM 参数、优化代码逻辑或更换垃圾回收器。

        3-1)调整 JVM 参数

  • 增大堆内存(-Xmx-Xms)。
  • 优化新生代与老年代比例(-XX:NewRatio)。

  • 启用并行 Full GC(-XX:+UseParallelOldGC)或 G1 GC(-XX:+UseG1GC)。

        3-2)代码优化

  • 避免内存泄漏(如未关闭的资源、静态集合缓存)。

  • 减少大对象分配(如分页加载数据)。

  • 使用软引用(SoftReference)或弱引用(WeakReference)管理缓存。

        3-3)使用 G1 垃圾回收器

  • G1 通过分区域回收减少 Full GC 的发生:

-XX:+UseG1GC -XX:MaxGCPauseMillis=200

更多java基础总结(适合于java基础学习、java面试常规题):

总结篇(1)---复用类

总结篇(2)---多态

总结篇(3)---内部类 (1)内部类的基本概念

总结篇(4)---内部类 (2)内部类之静态内部类

总结篇(5)---内部类 (3)内部类之成员内部类

总结篇(6)---内部类 (4)内部类之局部内部类

总结篇(7)---内部类 (5)内部类之匿名内部类

总结篇(8)---序列化

总结篇(9)---字符串及基本类 (1)字符串及基本类之基本数据类型

总结篇(10)---字符串及基本类 (2)字符串及基本类之java中公共方法及操作

总结篇(11)---字符串及基本类 (3)String对象

总结篇(12)---字符串及基本类 (4)Integer对象

总结篇(13)--- Java注解及元注解

总结篇(14)---JVM(java虚拟机) (1)JVM虚拟机概括

总结篇(15)---JVM(java虚拟机) (2)类加载器

总结篇(16)---JVM(java虚拟机) (3)运行时数据区

总结篇(17)---JVM(java虚拟机) (4)垃圾回收

总结篇(18)---JVM(java虚拟机) (5)垃圾回收算法

总结篇(19)---JVM(java虚拟机) (6)JVM调优

总结篇(20)---反射

总结篇(21)---Java IO

总结篇(22)---Java 进程

总结篇(23)---Java线程及其相关(1)线程介绍

总结篇(24)---Java线程及其相关(2)多线程及其问题

总结篇(25)---Java线程及其相关(3)线程池及其问题

总结篇(26)---Java线程及其相关(4)ThreadLocal

总结篇(27)---Java并发及锁(1)Synchronized

总结篇(28)---Java并发及锁(2)Volatile

总结篇(29)---Java并发及锁(3)Lock

总结篇(30)---Java并发及锁(4)常见锁及分类

总结篇(31)---JUC工具类(1)CountDownLatch

总结篇(32)---JUC工具类(2)CyclicBarrier

总结篇(33)---JUC工具类(3)Semaphore

总结篇(34)---JUC工具类(4)Exchanger

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

sun cat

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

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

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

打赏作者

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

抵扣说明:

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

余额充值