java回收对象
① java垃圾回收的优点和原理是什么回收机制是怎样的
优点:a.不需要考虑内存管理, b.可以有效的防止内存泄漏,有效的利用可使用的内存, c.由于有垃圾回收机制,Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"
原理:垃圾回收器是作为一个单独的低级别的线程运行,在不可知的情况下对内存堆中已死亡的或者长期没有使用的对象回收,但是不能实时的对某一对象或者所有对象进行垃圾回收。
垃圾回收机制:分代复制垃圾回收、标记垃圾回收、增量垃圾回收
GC(Gabage Collection)工作原理:当创建对象时,GC就开始监视这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理heap(堆)中的素有对象。通过这种方式确定哪些对象是“可达的”,哪些是“不可以达的”。
垃圾回收机制通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清理,我们虽然可以调用System.gc()让垃圾回收器运行,但依旧无法保证GC一定会执行。
② 在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对象符合以下条件便会被垃圾回收:
1.所有实例都没有活动线程访问。
2.没有被其他任何实例访问的循环引用实例。
3.Java 中有不同的引用类型。判断实例是否符合垃圾收集的条件都依赖于它的引用类型。
④ 在java中,对象什么时候可以被垃圾回收
通俗的说明白两点就理解了:
不用的对象,或者说无法再调用的对象会被回收
垃圾回收不是实时的,也就是只能考虑最早什么时候会被回收
Objectobj=newObject();//创建了一个对象,并定义一个变量obj指向它
obj=newObject();//又创建了一个对象,并将变量obj指向它,这时第一步创建的对象就被看作垃圾
注:你会了解,被看做垃圾的对象,是不会被程序再次调用的(即确实是垃圾)
⑤ java 怎么对一个对象强制垃圾回收
一、Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize()。
(1).对象不一定会被回收。
(2).垃圾回收不是析构函数。
(3).垃圾回收只与内存有关。
(4).垃圾回收和finalize()都是靠不住的,只要JVM还没有快到耗尽内存的地步,它是不会浪费时间进行垃圾回收的。
二、垃圾回收器:
1、在 Java 中,当创建一个对象时,Java 虚拟机(JVM)为该对象分配内存、调用构造函数并开始跟踪你使用的对象。当停止使用一个对象(就是说,当没有对该对象有效的引用时),JVM 通过垃圾回收器将该对象标记为释放状态。
2、当垃圾回收器将要释放一个对象的内存时,调用该对象的finalize() 方法(如果该对象定义了此方法)。垃圾回收器以独立的低优先级的方式运行,只有当其线程挂起等待该内存释放的情况出现时,才开始运行释放对象的内存。(事实上,可以调用System.gc() 方法强制垃圾回收器来释放这些对象的内存。)
3、在以上的描述中,有一些重要的事情需要注意。首先,只有当垃圾回收器释放该对象的内存时,才会执行finalize()。如果在 Applet 或应用程序退出之前垃圾回收器没有释放内存,垃圾回收器将不会调用finalize()。
三、finalize()方法的优缺点:
1、根据 Java 文档,finalize() 是一个用于释放非 Java 资源的方法。但是,JVM 有很大的可能不调用对象的finalize() 方法,因此很难证明使用该方法释放资源是有效的。
2、Java 1.1 通过提供一个System.runFinalizersOnExit() 方法部分地解决了这个问题。(不要将这个方法与 Java 1.0 中的System.runFinalizations() 方法相混淆。)不象System.gc() 方法那样,System.runFinalizersOnExit() 方法
总结:并不立即试图启动垃圾回收器。而是当应用程序或 Applet 退出时,调用每个对象的finalize() 方法。
⑥ java 里面如何尽快回收不用的对象
finalize方法是java.lang.Object里定义的方法,因为所有java对象继承于Object,因此每个对象都可以去实现这个方法。这个方法会在一个对象被垃圾回收时调用。
为c1,c2赋值为null可以使刚建立的两个circle对象处于“没有被引用”的状态(通俗的说,就是没有句柄指向这个对象,注意java没有指针的概念),这种状态下可以被垃圾回收。
而System.gc(),所谓gc就是garbage collection, 这个方法其实就是建议jvm去回收可以被垃圾回收的对象。 这个方法并不常用,因为一般垃圾回收都是自动完成的,并不需要人为控制。在这个例子中,只是为了能尽快看到finalize的执行。
注意java的垃圾回收机制有很大的不确定性,你不能确保某个可以被回收对象什么时候被回收,所以gc只是“建议”,并不能“确保”。
⑦ Java 的垃圾回收如何判断哪个对象可以被回收
java对象符合以下条件便会被垃圾回收:
1.所有实例都没有活动线程访问。
2.没有被其他任何实例访问的循环引用实例。
3.Java 中有不同的引用类型。判断实例是否符合垃圾收集的条件都依赖于它的引用类型。
在编译过程中作为一种优化技术,Java编译器能选择给实例赋null值,从而标记实例为可回收。
classAnimal{
publicstaticvoidmain(String[]args){
Animallion=newAnimal();
System.out.println("Mainiscompleted.");
}
protectedvoidfinalize(){
System.out.println("RestinPeace!");
}
}
⑧ java中可以主动回收人为认定的垃圾对象吗
答案是不可以!
java的gc机制是在底层设计的,可以让程序员不用想c语言那样回收对象,是为了编程方便和安全考虑的,如果人为可以回收的话,安全性就不能保证了,所以不能主动回收。
在代码中,对一些大对象,比如集合等,可以在方法结尾处,写上 list = null ,这样的,有利于gc的回收(未考证),另外可以在代码中用 System.gc(); 来执行垃圾回收,但是并不能控制回收哪些无用对象,这个操作知识显式地执行回收动作,但是回收的规则还是按照自动回收来的,所以即便是无用的对象,也可能回收,可能不回收。