我尝试编写一个类来计算内存中的实例数量。我使用了一个静态属性--在构造函数中递增它,在finalize方法中递减它。
您可以在下面看到Counter类。
在一个主类(TestCounter)中,我列出了计数器的列表。当我使用较小的值(java TestCounter 10100)测试这个类时,结果似乎很正常:
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个注释行)。现在几乎所有的实例都被解放了:
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()方法被调用了两次...
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 ... 你能解释一下这种行为吗?
也许我犯了个错误或者误解了什么..。
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");
}
}发布于 2014-11-19 18:49:52
我试过你的代码了。虽然我没有像你那样得到负number,但我被困住了:
curently : 923367 over 1000000 created
Still 1041 instances in memory... waiting ...
Still 1041 instances in memory... waiting ...
Still 1041 instances in memory... waiting ...然后我同步了number的增量/减量:
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,程序终止。
curently : 936759 over 1000000 created
at the end : 0 over 1000000 created结论:
对于同一个对象,finalize()不会被调用两次,但是当多个线程(主线程和GC线程)在不同步的情况下修改同一个变量时,可能会发生奇怪的事情。
https://stackoverflow.com/questions/27014430
复制相似问题