首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >finalize的多个调用

finalize的多个调用
EN

Stack Overflow用户
提问于 2014-11-19 18:24:54
回答 1查看 282关注 0票数 1

我尝试编写一个类来计算内存中的实例数量。我使用了一个静态属性--在构造函数中递增它,在finalize方法中递减它。

您可以在下面看到Counter类。

在一个主类(TestCounter)中,我列出了计数器的列表。当我使用较小的值(java TestCounter 10100)测试这个类时,结果似乎很正常:

代码语言:javascript
复制
Size of the list : : 0
curently : 100 over 100 created
Size of the list : : 0
curently : 200 over 200 created
Size of the list : : 0
curently : 300 over 300 created
Size of the list : : 0
curently : 400 over 400 created
Size of the list : : 0
curently : 500 over 500 created
Size of the list : : 0
curently : 600 over 600 created
Size of the list : : 0
curently : 700 over 700 created
Size of the list : : 0
curently : 800 over 800 created
Size of the list : : 0
curently : 900 over 900 created
Size of the list : : 0
curently : 1000 over 1000 created
Still 1000 instances in memory... waiting ...
Still 1000 instances in memory... waiting ...
Still 1000 instances in memory... waiting ...
Still 1000 instances in memory... waiting ...

当我读到this question的答案时,垃圾收集器不是必须调用的,所以我显式地调用了GC (3个注释行)。现在几乎所有的实例都被解放了:

代码语言:javascript
复制
curently : 10000 over 10000 created
Still 7435 instances in memory... waiting ...
at the end : 0 over 10000 created

有时,1或2个实例似乎会留在内存中……

但是如果我尝试使用更多的对象(java TestCounter 10 100000),结果是令人惊讶的。“实例数”可以是负数,这表明finalize()方法被调用了两次...

代码语言:javascript
复制
Size of the list : : 0
curently : 896577 over 1000000 created
Still 892834 instances in memory... waiting ...
Still -762 instances in memory... waiting ...
Still -762 instances in memory... waiting ...
Still -762 instances in memory... waiting ... 

你能解释一下这种行为吗?

也许我犯了个错误或者误解了什么..。

代码语言:javascript
复制
public class Counter{

    static long number = 0;
    static long totalNumber = 0;


    public Counter(){
        number++; 
        totalNumber++;

    }

    public static long getNumber(){
        return number;
    }

    public static long getNombreTotal(){
        return totalNumber;
    }

    protected void finalize() throws Throwable{
            try {       
                number--;
            } finally {
                super.finalize();
            }
    }

}

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TestCompteur{

    public static void methode(int iteration, int taille){

        for (int j=0; j<iteration; j++){

            ArrayList<Counter> liste = new ArrayList<Counter>();

            for (int i=0; i<taille; i++){
                liste.add(new Counter());
            }

            liste.clear();

            System.out.println("Size of the list : : "+liste.size());           
            System.out.println("curently : " + Counter.getNumber() + " over " + Counter.getNombreTotal() +" created");      
        }   



    }

    public static void main(String[] args){


        methode(Integer.decode(args[0]), Integer.decode(args[1]));

        /*
        System.gc();
        System.runFinalization();
        System.gc();
        */

        while (Counter.getNumber() != 0){
            //System.out.print(".");
            System.out.println("Still " + Counter.getNumber() + " instances in memory... waiting ...");

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(TestCompteur.class.getName()).log(Level.SEVERE, null, ex);
                    }
        }
        System.out.println("at the end : " + Counter.getNumber() + " over " + Counter.getNombreTotal() +" created");
    }

}
EN

回答 1

Stack Overflow用户

发布于 2014-11-19 18:49:52

我试过你的代码了。虽然我没有像你那样得到负number,但我被困住了:

代码语言:javascript
复制
curently : 923367 over 1000000 created
Still 1041 instances in memory... waiting ...
Still 1041 instances in memory... waiting ...
Still 1041 instances in memory... waiting ...

然后我同步了number的增量/减量:

代码语言:javascript
复制
public Counter()
{
    incNumber();
    totalNumber++;
}

public static synchronized void incNumber ()
{
    number++;
}

public static synchronized void decNumber ()
{
    number--;
}

protected void finalize() throws Throwable
{
    try {
        decNumber ();
    } finally {
        super.finalize();
    }
}

结果,number达到0,程序终止。

代码语言:javascript
复制
curently : 936759 over 1000000 created
at the end : 0 over 1000000 created

结论:

对于同一个对象,finalize()不会被调用两次,但是当多个线程(主线程和GC线程)在不同步的情况下修改同一个变量时,可能会发生奇怪的事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27014430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档