Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java终结器和gc_Java_Garbage Collection_Finalizer - Fatal编程技术网

java终结器和gc

java终结器和gc,java,garbage-collection,finalizer,Java,Garbage Collection,Finalizer,是时候质疑JAVA System.GC()和System.runFinilizer了 public interface SomeAction { public void doAction(); } public class SomePublisher { private List<SomeAction> actions = new ArrayList<SomeAction>(); public void subscribe(SomeSubscr

是时候质疑JAVA System.GC()和System.runFinilizer了

public interface SomeAction {
    public void doAction();
}

public class SomePublisher {
    private List<SomeAction> actions = new ArrayList<SomeAction>();

    public void subscribe(SomeSubscriber subscriber) {
        actions.add(subscriber.getAction());
    }
}

public class SomeSubscriber {
    public static int Count;

    public SomeSubscriber(SomePublisher publisher) {
        publisher.subscribe(this);
    }

    public SomeAction getAction() {
        final SomeSubscriber me = this;
        class Action implements SomeAction {

            @Override
            public void doAction() {
               me.doSomething();
            }
        }

        return new Action();
    }

    @Override
    protected void finalize() throws Throwable {
        SomeSubscriber.Count++;
    }

    private void doSomething() {
        // TODO: something
    }
}
公共接口操作{
公共无效行为();
}
公共类发布者{
私有列表操作=新建ArrayList();
公共无效订阅(SomeSubscriber){
actions.add(subscriber.getAction());
}
}
公共类订阅服务器{
公共静态整数计数;
公共SomeSubscriber(SomePublisher发布者){
publisher.subscribe(这个);
}
public SomeAction getAction(){
最终结果:me=此;
类动作实现了一些动作{
@凌驾
公共无效行为(){
我做某事;
}
}
返回新操作();
}
@凌驾
受保护的void finalize()抛出可丢弃的{
SomeSubscriber.Count++;
}
私人无效剂量(){
//托多:什么
}
}
现在我试图在主块中强制GC和终结器

 SomePublisher publisher = new SomePublisher();

        for (int i = 0; i < 10; i++) {
            SomeSubscriber subscriber = new SomeSubscriber(publisher);
            subscriber = null;
        }

        System.gc();
        System.runFinalization();

        System.out. println("The answer is: " + SomeSubscriber.Count);
SomePublisher=newsomepublisher();
对于(int i=0;i<10;i++){
SomeSubscriber=新的SomeSubscriber(发布者);
订户=null;
}
gc();
System.runFinalization();
系统退出。println(“答案是:“+SomeSubscriber.Count”);
由于JAVA GC调用不保证被调用(如javadoc中所述),并且由于JAVA GC调用不保证被调用(如javadoc和

我最初的想法是,它会输出随机的SomeSubscriber.Count。 (System.GC和终结器强制至少为“1”。)

相反,它总是0

有人能解释这种行为吗


(另外,静态成员字段是否独立于类实例而存在,并且在代码执行过程中永远不会被销毁?

您的测试有一个缺陷-即使假设调用
System.gc()
System.runFinalization()
将实际运行GC和终结,您创建的实例不是垃圾收集的候选实例,因此不会被终结或收集

您运行此行10次:

SomeSubscriber subscriber = new SomeSubscriber(publisher);
这将调用
SomeSubscriber
的构造函数,该构造函数表示:

publisher.subscribe(this);
因此,发布者对象被赋予了对当前正在构造的对象的引用。它用它做什么

actions.add(subscriber.getAction());
好的,它调用订阅服务器上的
getAction()
方法,并存储结果

public SomeAction getAction() {
    final SomeSubscriber me = this;
    class Action implements SomeAction {

        @Override
        public void doAction() {
           me.doSomething();
        }
    }

    return new Action();
}
它创建一个本地类的实例。该实例包含一个封闭的
SomeSubscriber
对象的实例。事实上,它有两个这样的实例-
me
,以及每个内部类对封闭实例的隐式引用。本地类是内部类

因此,当您在
publisher
实例中存储操作列表时,也会在其中存储对所有订阅者的引用,
publisher
实例仍处于活动状态,因此这些引用仍处于活动状态,因此您的
SomeSubscriber
实例实际上没有一个符合垃圾收集条件。


请确保您还分配了
publisher=null
,然后您可能会看到正在运行的定稿。我还建议将
Count
声明为
volatile
(并且不要将其称为
Count
,而是
Count
——变量应该以小写字母开头),因为终结器通常在不同的线程中运行。

如果您不知道什么是静态字段,那么不应该担心终结器或gc。静态字段是存在的类变量,没有实例化类实例共享的类。“不保证调用”的哪一部分你不明白吗?你不应该显式调用
System.gc()
。在最好的情况下,它不会做任何事情,在最坏的情况下,它总是会导致世界gc完全停止(例如,当CMS收集器正在使用时)。如果你看到techloris_109示例,System.gc()手动调用,并在实例为空后运行finalize块。为什么在我的情况下不会发生相同的情况?就是这样!所以问题不在于GC,而在于本地类引用!即使您解决了引用问题,finalize()也无法保证方法执行。请看:@ravindra这是真的,但是,这些测试通常会取得一些成功,并且是一个重要的学习工具。不过,正确地执行它们很重要。