首页 > 编程语言 >判断对象是否存活的算法

判断对象是否存活的算法

时间:2023-06-05 21:44:21浏览次数:43  
标签:info HOOK 对象 存活 算法 引用 logger SAVE

需要回收的位置如下

 其实垃圾回收是jvm自带的功能,所以有了如下的优缺点

优点:

1.项目开发的时候不需要开发人员考虑内存管理

2.可以有效的防止内存泄漏,更加高效的利用可使用的内存

3.因为垃圾回收不再有了作用于的概念

缺点:

因为不了解所以使用过程中会出现内存溢出和内存泄漏的问题

下面将判断对象存活的算法进行简单说明

引用计数算法:它的意思就是给每个创建的对象添加一个引用计数器,被引用计数值加1,引用失效时减一,当计数值为0时,表示该对象就不再被使用了

优点:

实现简单,执行效率高

缺点:

 检测不到循环引用

实际案例

 因为引用一直存在了,永远无法进行回收了,请注意java中的垃圾回收并没有使用引用计算算法

可达性分析算法:官方解释是通过一系列GC ROOTs 对象作为起始点,从起点开始向下搜索对象的路径,搜索所经过的路径称为引用链,当一个对象和任何一个GC ROOTs都没有引用链时,最终判断该对象不可用

先看图

 

再看下可以作为GC Roots的对象有哪些

1.栈帧中的局部变量表中的reference引用所引用的对象
2.方法区中static静态引用的对象
3.方法区中final常量引用的对象
4.本地方法栈中JNI(Native方法)引用的对象
5.Java虚拟机内部的引用, 如基本数据类型对应的Class对象, 一些常驻的异常对象(比如 NullPointExcepiton、
6.OutOfMemoryError) 等, 还有系统类加载器。
7.所有被同步锁(synchronized关键字) 持有的对象

8.反映Java虚拟机内部情况的JMXBean、 JVMTI中注册的回调、 本地代码缓存等

 这里可达性分析算法是java判断对象存活使用的

 但是这个时候的对象还并不能进入死亡,还需要再次的判断

下面通过模拟的程序进行说明

 

 代码部分

package com.java.test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.ref.PhantomReference;
import java.lang.ref.WeakReference;

/**
 * @Description:
 * @Author: qiuxie
 * @Create: 2023/6/2 14:18
 */
public class FinalizeEscapeGc {
    /**
     * 定义日志对象
     */
    private static final Logger logger= LoggerFactory.getLogger(FinalizeEscapeGc.class);

    public static FinalizeEscapeGc SAVE_HOOK=null;

    public void isAlive(){
        logger.info("是的,我仍然活着");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        logger.info("finalize 方法执行中");
        FinalizeEscapeGc.SAVE_HOOK=this;
    }

    public static void main(String[] args) {
        SAVE_HOOK=new FinalizeEscapeGc();
        logger.info("打印SAVE_HOOK:{}",SAVE_HOOK);
        //开始第一次的自救
        SAVE_HOOK=null;
        System.gc();
        //因为finalize()优先级比较低,设置等待0.5秒
        try {
            Thread.sleep(500);
            if (SAVE_HOOK!=null){
                logger.info("开始第一次判断是否存活");
                SAVE_HOOK.isAlive();
            }else {
                logger.info("第一次的自救 很抱歉,我已经死亡了");
            }
        } catch (InterruptedException e) {
            logger.error("睡眠异常:{}",e);
        }
        logger.info("第二次自救前 打印SAVE_HOOK:{}",SAVE_HOOK);
        //只能救一次,第二次自救会失败
        //开始第二次的自救
        SAVE_HOOK=null;
        System.gc();
        //因为finalize()优先级比较低,设置等待0.5秒
        try {
            Thread.sleep(500);
            if (SAVE_HOOK!=null){
                logger.info("开始第二次判断是否存活");
                SAVE_HOOK.isAlive();
            }else {
                logger.info("第二次的自救 很抱歉,我已经死亡了");
            }
        } catch (InterruptedException e) {
            logger.error("睡眠异常:{}",e);
        }

        logger.info("最后打印SAVE_HOOK:{}",SAVE_HOOK);

    }
}

  pom依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

  这个org.slf4j已经被包含在springboot了

下面给出两次标记的走向图

 注意点:finalize()执行缓慢,会有发生死循环的可能性,甚至最终导致内存回收子系统的崩溃

 

标签:info,HOOK,对象,存活,算法,引用,logger,SAVE
From: https://www.cnblogs.com/q202105271618/p/17445506.html

相关文章

  • 文心一言 VS 讯飞星火 VS chatgpt (32)-- 算法导论5.2 4题
    四、利用指示器随机变量来解如下的帽子核对问题(hat-heckproblem):n位顾客,他们每个人给餐厅核对帽子的服务生一顶帽子。服务生以随机顺序将帽子归还给顾客。请问拿到自己帽子的客户的期望数是多少?文心一言:我们可以将这个问题转化为求解在指示器随机变量基础上的期望值。已知......
  • 文心一言 VS 讯飞星火 VS chatgpt (32)-- 算法导论5.2 4题
    四、利用指示器随机变量来解如下的帽子核对问题(hat-heckproblem):n位顾客,他们每个人给餐厅核对帽子的服务生一顶帽子。服务生以随机顺序将帽子归还给顾客。请问拿到自己帽子的客户的期望数是多少?文心一言:我们可以将这个问题转化为求解在指示器随机变量基础上的期望值。已知有n位......
  • 算法——字符串(一)
    1、两数相加1classSolution{2publicListNodeaddTwoNumbers(ListNodel1,ListNodel2){3ListNodepre=newListNode();4ListNodecur=pre;5intcarry=0;6while(l1!=null||l2!=null||carry!=0){7......
  • 使用 TypeScript 探索面向对象编程
    在软件开发领域,面向对象编程(OOP)已成为创建复杂且可扩展应用程序的基本范例。支持OOP概念的最流行的编程语言之一是TypeScript。TypeScript是JavaScript的超集,它增加了静态类型和其他功能以增强代码的可维护性和可读性。在这篇博客中,我们将探讨TypeScript中面向对象编程......
  • 6.10 对象数组
    demo1对象数组,静态初始化classPerson{privateStringname;privateintage;publicPerson(Stringname,intage){this.name=name;this.age=age;}publicStringgetInfo(){return"姓名:"+this.name+"......
  • 数据结构--Dijkstra算法最清楚的讲解
    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止###基本思想通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算)。此外,引进两个集合S和U。S的......
  • 树之深度优先遍历算法详解(DFS实现) LeetCode94
           本文以如下树结构为例深度优先(DeepFirstSearch)       树的孩子称作子树,对于一个树进行深度优先遍历,即将其某一子树下所有节点遍历完再去遍历其他子树。遍历的顺序以根为参照可分为先序遍历,中序遍历,后序遍历。遍历方式描述先序遍历根左右中序遍历左根右后......
  • Hash表算法
    第一部分:TopK算法详解问题描述百度面试题:   搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。   假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个。一个查询串的重复度越高,......
  • K-Means算法--聚类算法
    在数据挖掘中,K-Means算法是一种clusteranalysis的算法,其主要是来计算数据聚集的算法,主要通过不断地取离种子点最近均值的算法。问题K-Means算法主要解决的问题如下图所示。我们可以看到,在图的左边有一些点,我们用肉眼可以看出来有四个点群,但是我们怎么通过计算机程序找出这几个点群......
  • java基础语法02-面向对象编程
    1面向对象基础1.1方法1.2构造方法1.3方法重载1.4继承1.5多态1.6抽象类1.7接口1.8静态字段和静态方法1.9包1.10作用域1.11内部类1.12classpath和jar1.13class版本1.14模块2java核心类......