Java教程

JVM垃圾回收机制入门

本文主要是介绍JVM垃圾回收机制入门,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

JVM垃圾回收机制入门

  • 前言
  • 一、垃圾回收原理与算法
    • 1、内存管理
    • 2、垃圾回收过程
    • 3、垃圾回收算法
  • 二、通用的分代垃圾回收机制
    • Minor GC、Major GC、Full GC
  • 三、JVM调优和Full GC
  • 四、内存泄漏操作
  • 总结
  • 参考文献

前言

简单理解JVM垃圾回收机制,需先了解JVM内存分析入门.

一、垃圾回收原理与算法

1、内存管理

内存管理一定程度上就是对堆中对象的管理,管理对象的空间分配和释放。
1)空间分配,通过new关键字来分配内存。
2)空间释放,通过将对象赋值为null,然后垃圾回收机制检测到对象“不可达”时,将内存回收。比如一个对象没有被引用时。

2、垃圾回收过程

垃圾回收线程GC线程会随着JVM的启动一直伴随着其结束,这个线程专门来回收垃圾,主要做两件事
1)发现垃圾,发现无用对象。
2)回收垃圾,回收无用对象占用的内存空间。
在这里插入图片描述
这里的0x12 和 0x13处的对象就无引用,可以作为垃圾回收,为堆中腾出更多的空间,毕竟以后编程是服务端编程,资源不仅宝贵,而且访问的用户很多。

3、垃圾回收算法

1)引用计数法,通过记录对象引用的次数,当引用次数为0时,回收该对象的资源。但是确定也很明显。

package com.xhu.java;

public class Person {
    String name;
    Person friend;

    public static void main(String[] args) {
        Person p1 = new Person();
        Person p2 = new Person();
        p1.friend = p2;
        p2.friend = p1;
        p1 = p2 = null;
    }
}

在这里插入图片描述
当把这两个引用赋值为null时,但这两个对象还相互引用,永远就不能当垃圾回收,造成内存泄露。
2)引用可达法,程序把所有引用关系看作一张图,从一个节点GC ROOT开始,寻找对应的引用节点,继续寻找已找到节点的引用节点,当所有引用节点寻找完毕后,剩余节点被认为“不可达”对象,将作为垃圾回收。
3)其它算法。

二、通用的分代垃圾回收机制

由于不同对象的生命周期不一样,为了提高回收效率,不同生命周期的对象以不同的回收方式处理。
将对象状态分为三种:年轻代、老年代、永久代。将处于不同状态的对象放到堆中不同区域。JVM将堆内存划分为Eden、Survivor、Tenured/Old空间。
1)年轻代,刚生成的对象放入Eden区,目的就是尽可能收掉哪些生命周期短的对象,对应的Minor GC,当年轻代区域放满时,Minor GC就开始请理,把无用对象的内存回收,而还在生命周期内的对象就复制到年老代区域。
在这里插入图片描述
步骤)先Eden区满,清理,将还存活的对象复制到Survivior1区,Survivor一区满,将无引用的对象回收其内存,还存活的对象复制到Survivor2区,Survivor2区满,又复制到1区,反复15次(默认值),还有对象存活,就把该对象复制到Tenured/Old区。
2)年老代
随着年老代的对象越来越多,就需要启动Major GC、Full GC(全量回收),来一次大扫除,全面清理年轻代和年老代区域的对象。
3)永久区
用于存放静态文件,Java类、方法等,永久代对垃圾回收没有显著影响。JDK7以前是方法区,JDK8以后,就没有永久代了,而是直接内存的Meta-Space元数据空间和堆代替。

Minor GC、Major GC、Full GC

1)Minor GC
用于清理年轻代区域,Eden区满就会触发一次Minor GC,清理无用对象,将存活对象复制到Survivor1、2区。
2)Major GC
用于清理老年代区域。
3)Full GC
用于清理年轻代、老年代区域,大扫除,对系统性能会有影响。

三、JVM调优和Full GC

在对JVM调优的过程中,很大一部分工作就是对Full GC的调节。导致Full GC调用的可能情况。
1)年老代(Tenured)被写满
2)持久代(Perm)被写满
3)System.gc()被显示调用,调用该函数,Full GC不一定执行,JVM会通过实际情况来是否需要调Full GC,程序员无权调用GC。
4)上一次GC之后,heap区分配策略动态变化。

四、内存泄漏操作

1)创建大量无用对象

String str = "";
        for (int i = 0; i < 10000; i++) {
            str += i;//
        }

在这里插入图片描述
每一次加一个值,都会导致new 一个新的string对象,而中间都产生了大量无用string对象。大量字符串拼接时,可以使用单线程不安全的StringBuilder或者使用多线程安全的StringBuffer。
2)静态集合类的使用
Map、List,这些静态变量的生命周期和应用程序一致,所有对象的Object也不能被释放。
3)各种连接对象未关闭
I/O流、数据连接对象、网络连接对象。
4)监听器的的使用
释放对象时,没有释放相应的监听器。

总结

1)垃圾回收原理与算法
a、内存管理
b、垃圾回收过程
c、垃圾回收算法
2)通用的分代垃圾回收机制
Minor GC、Major GC、Full GC
3)JVM调优和Full GC
4)内存泄漏操作

参考文献

[1] 尚硅谷Java SE–高淇

这篇关于JVM垃圾回收机制入门的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!