垃圾收集器(一)

近期学习了JVM垃圾收集器与内存分配策略,现将部分学习笔记记录如下,以供今后使用。

前言

为了能使Java应用程序正常运行,JVM将内存数据分为程序计数器、虚拟机栈、本地方法栈、Java堆和方法区5个区域。其中程序计数器、虚拟机栈、本地方法栈3个区域是线程私有的,其生命随线程而生,随线程而亡;栈中的栈帧随着方法的进入和退出而执行着入栈和出栈操作,每个栈帧中分配的内存基本上在类结构确定时就已知了,因此这几个区域的内存分配与回收都是确定的,在这几个区域就不需要过多的考虑内存回收问题。而Java堆与方法区则完全不同,一个接口的多个实现类需要的内存可能不同,我们只有在程序运行期间才能知道创建哪些对象,需要分配多少内存,所以这部分内存的分配与回收是动态的,垃圾收集器所关注的就是这部分内存。
既然垃圾收集器关注的是Java堆与方法区的内存回收问题,那么最重要的一个问题就是:哪些内存需要回收?
下面介绍解决这个问题的常用算法。

引用计数算法(Reference Counting)

引用计数算法原理:给对象添加一个引用计数器,每当有一个地方引用它时,计数器加1;当引用失效时,计数器减1;任何时刻计数器为0的对象就是不能被使用的对象。
引用计数算法实现简单,判断效率很高;但JVM没有使用该算法管理内存,主要原因是它很难解决对象间的循环引用问题。

public class ReferenceCountingGC {
    public Object instance;

    public static void testGC() {
        ReferenceCountingGC objA = new ReferenceCountingGC(); // objACount = 1
        ReferenceCountingGC objB = new ReferenceCountingGC(); // objBCount = 1
        objA.instance = objB; // objBCount = 2
        objB.instance = objA; // objACount = 2

        objA = null; // objACount = 1
        objB = null; // objBCount = 1

        // 此时进行垃圾回收,objA与objB的引用计数器都不为0,这两个对象不会被回收
        System.gc();
    }
}

可达性分析算法

可达性分析算法的原理:通过一系列的称为“GC Roots”的对象作为起点,从这个借口开始向下搜索,搜索所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连时,则此对象不可用。
Java语言中,可作为 GC Roots 的对象包括以下几种:
- 虚拟机栈(栈帧中的本地变量表)中的引用的对象;
- 方法区中类的静态属性引用的对象;
- 方法区中常量引用的对象;
- 本地方法栈中JNI(Native方法)引用的对象。

生存还是死亡

即使在可达性分析算法中不可达的对象,也并非是非死不可的,一个对象在真正死亡之前,至少要经历两次标记过程。
如果对象在进行可达性分析后发现没有与 GC Roots 相连接的引用链,那么它将被第一次标记并进行一次筛选,筛选条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或finalize()方法已被虚拟机调用过,则虚拟机认为没有必要执行finalize()方法。
如果该对象被判定为有必要执行finalize()方法,那么该对象将会被放置在F-Queue队列中,并在稍后由低优先级的Finalizer线程(一个由虚拟机自动建立的线程)去执行它。finalize()方法是对象逃脱死亡的最后一次机会,稍后GC将对F-Queue中的对象进行第二次标记,如果对象在finalize()方法中成功拯救自己(只需要重新与引用链上的任何对象建立关联即可,如把自己this复制给某个类变量或对象的成员变量),那么在第二次标记时它将被移除“即将回收”的集合;否则,这个对象就会被回收了。
任何一个对象的finalize()方法都只会被系统自动调用一次,因此对象也只有在第一次被调用finalize()方法时拯救自己一次,后续再被回收,它的finalize()方法不会被再次执行,也就无法自救了。

public class FinalizeEscapeGC {
    public static FinalizeEscapeGC instance;

    public void isAlive() {
        System.out.println("Yes, i'm still alive!");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize() executed!");
        FinalizeEscapeGC.instance = this;
    }

    public static void main(String[] args) throws InterruptedException {
        FinalizeEscapeGC.instance = new FinalizeEscapeGC();

        // 第一次回收时对象拯救自己
        FinalizeEscapeGC.instance = null;
        System.gc();
        // 等待1s,让gc执行
        Thread.sleep(1000);
        if (FinalizeEscapeGC.instance != null) {
            FinalizeEscapeGC.instance.isAlive();
        } else {
            System.out.println("Oh, i'm dead!");
        }

        // 第二次拯救自己是否能成功呢?看运行结果
        FinalizeEscapeGC.instance = null;
        System.gc();
        Thread.sleep(1000);
        if (FinalizeEscapeGC.instance != null) {
            FinalizeEscapeGC.instance.isAlive();
        } else {
            System.out.println("Oh, i'm dead!");
        }
    }
}

运行结果:
finalize() executed!
Yes, i'm still alive!
Oh, i'm dead!

从运行结果看,对象第一次被回收时拯救自己成功了,但第二次被回收时拯救自己失败了。

回收方法区

永久代的垃圾收集主要回收两部分内容:废弃常量和无用的类。
如果没有任何对象引用常量池中的常量,对于针对字符串常量也需要没有其他地方引用这个字面量,那么发生内存回收时,这些常量有可能会被系统清理出常量池。
类需要同时满足以下3个条件才能算是无用的类:
- 该类的所有实例都已经被回收,即Java堆中不存在该类的任何实例;
- 加载该类的类加载器已经被回收;
- 该类对象的Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

JVM提供以下参数,可以查看类加载与卸载信息:
-XX:+TraceClassLoading 查看类加载信息。
-XX:+TraceClassUnLoading 查看类卸载信息。

基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值