博客
关于我
JVM--内存管理
阅读量:511 次
发布时间:2019-03-07

本文共 2098 字,大约阅读时间需要 6 分钟。

垃圾回收机制详解

垃圾回收是Java Virtual Machine(JVM)中最为关键的自动内存管理机制之一,负责回收内存空间中的不再被引用(即垃圾)的对象,从而防止内存泄漏和垃圾堆积的问题。

本文将深入探讨垃圾回收的相关知识,包括CMSG1垃圾回收算法的区别、垃圾回收的触发条件以及System.gc()的使用方法,并将介绍堆外内存的概念及其应用。


1. 垃圾回收的目的

垃圾回收的核心目标在于为了程序运行的稳定性和性能,最小化内存浪费。现代垃圾回收器通过复制标记-清除或标记-整理等算法,实现内存的高效利用。


2. CMS与G1垃圾回收器的区别

1. 目的

  • CMS(并行标记-清除):优先目标是最小化垃圾回收的停顿时间,适合对响应时间要求较高的如互联网应用。
  • G1(分代收集):追求低停顿且可预测的垃圾回收,同时兼顾全局内存管理,适合服务端应用。

2. 回收的代

  • CMS:只回收老年代。
  • G1:同时回收新生代和老年代。

3. 算法特点

  • CMS:使用标记-清除算法,操作相对简单,但导致内存碎片。
  • G1:使用标记-整理(整体)和复制(局部)结合,空间利用率更高。

4. 操作流程

  • CMS:初始标记 → 并发标记 → 重新标记 → 并发清理。
  • G1:初始标记 → 并发标记 → 最终标记 → 筛选回收。

5. 优缺点对比

  • CMS

    • 优点:并发执行,低停顿。
    • 缺点:对CPU敏感,容易触发并发模式失败(Concurrent Mode Failure)。
    • 缺点:难以处理浮动垃圾,可能线判断到“Concurrent Mode Failure”。
  • G1

    • 优点:
      • 并行与并发:充分利用多核优势,缩短停顿时间。
      • 分代收集:灵活管理新生代和老年代。
      • 空间整合:无内存碎片。
      • 可预测性:提供稳定的停顿时间模型。
    • 缺点:相较于CMS,G1在处理浮动垃圾时可能频繁触发Full GC。

此外,G1的分代收集机制使其在新生代垃圾回收和老年代垃圾回收上都能独立执行,这一特性使得G1在高并发环境中表现更优。


3. 垃圾回收的触发条件

1. Minor GC(新生代回收)

  • 触发条件:当新对象生成时,内存空间不足,导致应用程序申请内存失败。

2. Full GC(旧-generation回收)

  • 触发条件:
    • 老年代满额(尝试在老年代分配空间时失败)。
    • 持久代(Perm)被写满。
    • 显式调用System.gc()
    • 最后一次GC后的内存分配策略发生变化。
    • RMI定时调用。
    • 上一次GC后的悲观算法判断。

4. System.gc()的使用

  • 作用:通知JVM执行垃圾回收。虚拟机会根据自身策略决定是否与此时执行GC有关。
  • 注意事项
    • 不要频繁调用System.gc(),建议代码健壮,避免不必要的内存回收请求。
    • System.gc()是一个异步调用,垃圾回收不会立即执行。

示例:

public class Person {    public Person() {        System.out.println("person created");    }    @Override    protected void finalize() throws Throwable {        System.out.println("gc执行");        throw new Exception("无具体效果");    }}public class Demo {    public static void main(String[] args) {        Person per = new Person();        per = null;        System.gc();        System.out.println("hello world");    }}

执行结果显示gc会在hello world之后输出,且不会造成性能显著下降。


5. 堆外内存介绍

堆外内存(Direct Memory)是JVM中的一种高效内存管理方式,主要用于高并发场景中以减少内存拷贝时间和GC压力。

优点:

  • 提升IO效率:避免数据从堆内存到磁盘或网络设备进行双向拷贝。
  • 减少GC压力:堆外内存不参与JVM的内存管理,具有独立的回收机制。
  • 缺点:

    • 分配与释放耗时长:通过对象池管理可以有效缓解。
    • 默认内存极限:默认为64MB,超过限制会抛出OutOfMemoryError异常。

    使用方法:

  • 分配:
    ByteBuffer buffer = ByteBuffer.allocateDirect(10 * 1024 * 1024);
  • 回收:
    • 等待JVM进行Full GC时,堆外内存会被自动回收。

  • 6. 为什么堆外内存能提升IO效率?

    堆外内存直接与硬件进行通信,减少了从堆内到硬件的数据复制过程。当数据直接写入堆外内存时,电路层可以进行优化,从而提升数据传输效率。


    本文探讨了垃圾回收的核心机制、CMS与G1的区别以及堆外内存的应用价值。理解这些概念对优化Java程序性能具有重要意义。

    转载地址:http://chvjz.baihongyu.com/

    你可能感兴趣的文章
    mysql 协议的退出命令包及解析
    查看>>
    mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
    查看>>
    mysql 四种存储引擎
    查看>>
    MySQL 基础模块的面试题总结
    查看>>
    MySQL 备份 Xtrabackup
    查看>>
    mysql 多个表关联查询查询时间长的问题
    查看>>
    mySQL 多个表求多个count
    查看>>
    mysql 多字段删除重复数据,保留最小id数据
    查看>>
    MySQL 多表联合查询:UNION 和 JOIN 分析
    查看>>
    MySQL 大数据量快速插入方法和语句优化
    查看>>
    mysql 如何给SQL添加索引
    查看>>
    mysql 字段区分大小写
    查看>>
    mysql 字段合并问题(group_concat)
    查看>>
    mysql 字段类型类型
    查看>>
    MySQL 字符串截取函数,字段截取,字符串截取
    查看>>
    MySQL 存储引擎
    查看>>
    mysql 存储过程 注入_mysql 视图 事务 存储过程 SQL注入
    查看>>
    MySQL 存储过程参数:in、out、inout
    查看>>
    mysql 存储过程每隔一段时间执行一次
    查看>>
    mysql 存在update不存在insert
    查看>>