博客
关于我
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/

    你可能感兴趣的文章
    Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
    查看>>
    NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
    查看>>
    NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
    查看>>
    NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
    查看>>
    NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
    查看>>
    NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
    查看>>
    NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
    查看>>
    NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
    查看>>
    NIFI大数据进阶_离线同步MySql数据到HDFS_01_实际操作---大数据之Nifi工作笔记0029
    查看>>
    NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
    查看>>
    NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
    查看>>
    NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
    查看>>
    NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
    查看>>
    NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
    查看>>
    NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
    查看>>
    NIH发布包含10600张CT图像数据库 为AI算法测试铺路
    查看>>
    Nim教程【十二】
    查看>>
    Nim游戏
    查看>>
    NIO ByteBuffer实现原理
    查看>>
    Nio ByteBuffer组件读写指针切换原理与常用方法
    查看>>