Java垃圾回收机制

本文介绍了Java内存机制,包括栈内存、堆内存、data segment(静态域和常量池)以及垃圾回收的工作原理,如引用计数器和可达性分析算法。此外,还讨论了不同级别的引用(强引用、软引用、弱引用、虚引用)和常见的垃圾回收算法,如标记-清除、复制、标记整理和分代收集算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java内存机制

java内存主要分成两类,一种是栈内存,一种是堆内存。

补充:

按照一个例子来:

public class Person {
    private String name;
    private int age;
    private static int eyesNum;


    public static void main(String[] args){
        Person p=new Person();
    }
    public static int getEyesNum(){
        return eyesNum;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public static void setEyesNum(int eyesNum) {
        Person.eyesNum = eyesNum;
    }
}

在这里插入图片描述

栈内存

主要存放在函数中定义的变量以及一些对象的引用。可以明确的是这部分是存放一些函数的局部变量以及一些实例对象的引用,这些都在超过这些变量的作用于之后就会自动销毁,因此此部分内存不会占用很多的内存空间。

堆内存

一个java虚拟机实例只存在一个堆空间,所有线程都共享这个堆。

主要存放一些new 的对象实例以及数组。这部分是不会超过作用域就自动销毁,这部分内存是由Java虚拟机的自动垃圾回收器管理的。那什么时候这个地方会被认为成垃圾然后回收呢?当在这里new的对象长时间没有被引用(相关的引用是放在栈内存中的)的时候就会被认为是垃圾,交给jvm进行垃圾回收。

基本类型的变量:int a=3//这个是看做int类型的引用

data segment

静态域

存放在对象中用static定义的静态成员(即静态变量,同理,如果该静态变量是基本类型则将变量名和值存入静态域,如果是引用类型则指向new出的对象)

常量池

存放定义的一些值以及一些符号描述等

例子

1、String str=“abc";static int a=2;Person p=new Person();int arry[]=new int[3];s[0]=1;s[2]=2;s[3]=3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0hDvpFz7-1600152884188)(C:\Users\PanQS\Desktop\Java垃圾回收\Java内存.png)]

Java垃圾回收

首先对于Java的垃圾回收需要明确的是,Java的垃圾回收不需要程序员去控制,而相关的垃圾回收是交给JVM去做的。jre会在后台自动进行垃圾回收,会回收那些不再使用的内存,这种机制就是垃圾回收机制。(GC)因此也可以知道所谓的垃圾回收要做的其实就是两件事情,一件就是明确哪些是垃圾,另一方面就是回收方法。

为什么要在垃圾回收之前明确Java的内存呢,就是Java的垃圾回收主要是针对堆内存,因为其他部分随着线程的结束,他的内存会自动自动销毁,而堆内存不是,所以垃圾回收工作主要是针对这个部分。

文章参考:https://www.cnblogs.com/czwbig/p/11127159.html(这个文章很丰富,我只是依据这个文章简单理解)

判断哪些对象需要垃圾回收(怎么判断是不是个垃圾)

1、引用计数器

这个应该都可以想到,就是对这个对象的引用次数进行计数,内引用则引用值加1,引用失效则引用值减1.直到最终引用数量为0,则认为其是个垃圾。这个当然很简单,但是当然也会有缺点,就是无法解决对象之间的循环引用的问题,这个就是当两个对象之间相互引用,但是都没有什么作用了,却都不被认为是垃圾都存在。

2、可达性分析

从“GC Root”向下搜索,走过的路径就是引用链,当一个对象到“GC root”不可达时就认为是垃圾。

可能的“GC Root”:

(1)虚拟栈中引用的对象

(2)方法区中常量引用的对象

(3)方法区中静态属性引用的变量

(4)本地方法引用的对象

这个当不可达的时候仅仅是指可以被回收,之后要经过两次标记。第一次是明确该对象是否有必要进行finalize(),当没有覆盖finalize()方法以及引用过这个方法都会认为是没有必要,则再次进行第二次标记。然后才会回收。需要注意的是finalize()方法仅仅只能运行一次。

引用级别

引用级别分成强引用、软引用、弱引用以及虚引用

强引用:永远不会被删除。就是Person p=new Person()就是强引用

软引用:在发生内存溢出异常的时候

弱引用: 只能生存到下一次垃圾收集发生之前

虚引用:无法通过虚引用获得一个对象实例,这个的目的仅仅是这个对象被回收的时候的一个系统通知。

垃圾回收算法

  1. 标记-清除算法

    这个就是把垃圾回收工作分成两个部分,首先标记处可以回收的对象,然后在标记完毕之后进行清理。效率低,并且空间碎片比较多。

  2. 复制算法

    这个就是把内存分成两块,先只使用其中的一块,进行垃圾清理的时候,先将存活得复制到另一块中,这样就有完整的内存了,解决了空间碎片的问题。

  3. 标记整理算法

标记完毕之后进行清理。效率低,并且空间碎片比较多。

  1. 复制算法

    这个就是把内存分成两块,先只使用其中的一块,进行垃圾清理的时候,先将存活得复制到另一块中,这样就有完整的内存了,解决了空间碎片的问题。

  2. 标记整理算法

  3. 分代收集算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值