java对象什么时候被回收?在java中,对象什么时候可以被垃圾回收
今天给各位分享java对象什么时候被回收的知识,其中也会对在java中,对象什么时候可以被垃圾回收进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
java的类加载后什么时候会被释放
java的类加载后且当使用阶段完成之后,java类就进入了卸载阶段,也就是所谓的释放。
使用阶段包括主动引用和被动引用,主动饮用会引起类的初始化,而被动引用不会引起类的初始化。
一个java类的完整的生命周期会经历加载、连接、初始化、使用、和卸载五个阶段,当然也有在加载或者连接之后没有被初始化就直接被使用的情况,如图所示:
PS:关于类的卸载,在类使用完之后,如果满足下面的情况,类就会被卸载:
该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。
加载该类的ClassLoader已经被回收。
该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。
如果以上三个条件全部满足,jvm就会在方法区垃圾回收的时候对类进行卸载,类的卸载过程其实就是在方法区中清空类信息,java类的整个生命周期就结束了。
在java中,对象什么时候可以被垃圾回收
1.引用计数器算法
解释
系统给每个对象添加一个引用计数器,每当有一个地方引用这个对象的时候,计数器就加1,当引用失效的时候,计数器就减1,在任何一个时刻计数器为0的对象就是不可能被使用的对象,因为没有任何地方持有这个引用,这时这个对象就被视为内存垃圾,等待被虚拟机回收
优点
客观的说,引用计数器算法,他的实现很简单,判定的效率很高,在大部分情况下这都是相当不错的算法
其实,很多案例中都使用了这种算法,比如 IOS的Object-C,微软的COM技术(用于给window开发驱动,.net里面的技术几乎都是建立在COM上的),Python语言等.
缺陷
无法解决循环引用的问题.
这就好像是悬崖边的人采集草药的人,想要活下去就必须要有一根绳子绑在悬崖上.如果有两个人,甲的手拉着悬崖,乙的手拉着甲,那么这两个人都能活,但是,如果甲的手拉着乙,乙的手也拉着甲,虽然这两个人都认为自己被别人拉着,但是一样会掉下悬崖.
比如说 A对象的一个属性引用B,B对象的一个属性同时引用A A.b= B() B.a= A();这个A,B对象的计数器都是1,可是,如果没有其他任何地方引用A,B对象的时候,A,B对象其实在系统中是无法发挥任何作用的,既然无法发挥作用,那就应该被视作内存垃圾予以清理掉,可是因为此时A,B的计数器的值都是1,虚拟机就无法回收A,B对象,这样就会造成内存浪费,这在计算机系统中是不可容忍的.
解决办法
在语言层面处理,例如Object-C就使用强弱引用类型来解决问题.强引用计数器加1,弱引用不增加
Java中也有强弱引用
2.可达性分析算法
解释
这种算法通过一系列成为"GC Roots"的对象作为起始点,从这些节点开始向下搜索所有走过的路径成为引用链(Reference Chain),当一个对象GC Roots没有任何引用链相连(用图论的话来说就是从GC Roots到这个对象不可达),则证明此对象是不可用的
优点
这个算法可以轻松的解决循环引用的问题
大部分的主流java虚拟机使用的都是这种算法
3. Java语言中的GC Roots
在虚拟机栈(其实是栈帧中的本地变量表)中引用的对象
在方法区中的类静态属性引用对象
在方法区中的常量引用的对象
在本地方法栈中JNI(即一般说的Native方法)的引用对象
java字符串实例化被回收的具体时间点
一是,在没有引用指向该字符串的引用时,会被回收;二是,在main方法结束后,与static变量一样被回收。
拓展字符串是 Java中特殊的类,使用方法像一般的基本数据类型,被广泛应用在 Java编程中。Java没有内置的字符串类型,而是在标准 Java类库中提供了一个 String类来创建和操作字符串。
在 Java中定义一个字符串最简单的方法是用双引号把它包围起来。这种用双引号括起来的一串字符实际上都是 String对象,如字符串“Hello”在编译后即成为 String对象。因此也可以通过创建 String类的实例来定义字符串。
不论使用哪种形式创建字符串,字符串对象一旦被创建,其值是不能改变的,但可以使用其他变量重新赋值的方式进行更改
在Java中,对象什么时候可以被垃圾回收
1.引用计数器算法
解释
系统给每个对象添加一个引用计数器,每当有一个地方引用这个对象的时候,计数器就加1,当引用失效的时候,计数器就减1,在任何一个时刻计数器为0的对象就是不可能被使用的对象,因为没有任何地方持有这个引用,这时这个对象就被视为内存垃圾,等待被虚拟机回收
优点
客观的说,引用计数器算法,他的实现很简单,判定的效率很高,在大部分情况下这都是相当不错的算法
其实,很多案例中都使用了这种算法,比如 IOS的Object-C,微软的COM技术(用于给window开发驱动,.net里面的技术几乎都是建立在COM上的),Python语言等.
缺陷
无法解决循环引用的问题.
这就好像是悬崖边的人采集草药的人,想要活下去就必须要有一根绳子绑在悬崖上.如果有两个人,甲的手拉着悬崖,乙的手拉着甲,那么这两个人都能活,但是,如果甲的手拉着乙,乙的手也拉着甲,虽然这两个人都认为自己被别人拉着,但是一样会掉下悬崖.
比如说 A对象的一个属性引用B,B对象的一个属性同时引用A A.b= B() B.a= A();这个A,B对象的计数器都是1,可是,如果没有其他任何地方引用A,B对象的时候,A,B对象其实在系统中是无法发挥任何作用的,既然无法发挥作用,那就应该被视作内存垃圾予以清理掉,可是因为此时A,B的计数器的值都是1,虚拟机就无法回收A,B对象,这样就会造成内存浪费,这在计算机系统中是不可容忍的.
解决办法
在语言层面处理,例如Object-C就使用强弱引用类型来解决问题.强引用计数器加1,弱引用不增加
Java中也有强弱引用
2.可达性分析算法
解释
这种算法通过一系列成为"GC Roots"的对象作为起始点,从这些节点开始向下搜索所有走过的路径成为引用链(Reference Chain),当一个对象GC Roots没有任何引用链相连(用图论的话来说就是从GC Roots到这个对象不可达),则证明此对象是不可用的
优点
这个算法可以轻松的解决循环引用的问题
大部分的主流java虚拟机使用的都是这种算法
3. Java语言中的GC Roots
在虚拟机栈(其实是栈帧中的本地变量表)中引用的对象
在方法区中的类静态属性引用对象
在方法区中的常量引用的对象
在本地方法栈中JNI(即一般说的Native方法)的引用对象
文章分享结束,java对象什么时候被回收和在java中,对象什么时候可以被垃圾回收的答案你都知道了吗?欢迎再次光临本站哦!