Java - 两次调用 System.gc 可以释放底层对象两次吗?
Java - Can calling System.gc two times release underlying object twice?
我有一个 Java 程序调用我的 C++ 库。 JNI-C++ 桥接是使用 SWIG 创建的
我对 Java 比较陌生,正在尝试了解 System.gc & System.runFinalization
下面的代码导致 SIGABRT,杀死我的应用程序(10 次运行中有 2 次)
public static void main (String[] args)
{
try
{
doSomeStuff();
} catch(Exception ex)
{
System.out.println(ex.getMessage());
} finally {
System.runFinalization();
System.gc();
}
}
void doSomeStuff()
{
try
{
sampleCppClass cppClass = new sampleCppClass();
/*
* do some stuff with Cpp obj
*/
} catch (Exception ex)
{
System.out.println(ex.getMessage());
} finally {
System.runFinalization();
System.gc();
}
}
而这个工作正常
public static void main (String[] args)
{
try
{
doSomeStuff();
} catch(Exception ex)
{
System.out.println(ex.getMessage());
} finally {
System.runFinalization();
System.gc();
}
}
void doSomeStuff()
{
try
{
sampleCppClass cppClass = new sampleCppClass();
/*
* do some stuff with Cpp obj
*/
} catch (Exception ex)
{
System.out.println(ex.getMessage());
}
}
我知道 System.gc() 和 System.runFinalization() 是不确定的 (Source-1, Source-2 and Source-3)。
doSomeStuff 中的 System.gc() 会被执行并释放对象吗?
稍后,主程序中的 System.gc() 运行并尝试释放同一个对象导致崩溃?如果确实如此,是否有办法证明这一点(logs/prints 以显示 gc 释放的对象的顺序)?
这样 post, explains causes of SIGABRT
因为我 运行 处于发布模式,所以我的 C++ 库没有任何 assert/abort。因此,我担心 double/multiple 考虑对象的空闲。
Can it so happen that the System.gc()
in doSomeStuff()
gets executed & free's the obj.
是的,但也可能什么都不做。
Later on, the System.gc()
in main runs & tries to free the same obj causing a crash?
没有。这是垃圾收集,而不是 C++ 销毁。每个对象只发生一次,或者永远不会发生。
就此代码而言,您的问题的根本原因是您的 gc()
和 runFinalization()
调用顺序错误。 runFinalization()
如果没有先前的 GC,则不执行任何操作。它执行仅由 GC 填充的终结器队列。
因此,当您全部执行两次时,只有第二次 runFinalization()
可以执行任何操作。这大概会在您的 SampleCPPClass
中执行一个终结器,它似乎有一个错误,显然是在本机代码中。
但是由于您还没有发布相关代码,因此无法进一步评论。
我有一个 Java 程序调用我的 C++ 库。 JNI-C++ 桥接是使用 SWIG 创建的
我对 Java 比较陌生,正在尝试了解 System.gc & System.runFinalization
下面的代码导致 SIGABRT,杀死我的应用程序(10 次运行中有 2 次)
public static void main (String[] args)
{
try
{
doSomeStuff();
} catch(Exception ex)
{
System.out.println(ex.getMessage());
} finally {
System.runFinalization();
System.gc();
}
}
void doSomeStuff()
{
try
{
sampleCppClass cppClass = new sampleCppClass();
/*
* do some stuff with Cpp obj
*/
} catch (Exception ex)
{
System.out.println(ex.getMessage());
} finally {
System.runFinalization();
System.gc();
}
}
而这个工作正常
public static void main (String[] args)
{
try
{
doSomeStuff();
} catch(Exception ex)
{
System.out.println(ex.getMessage());
} finally {
System.runFinalization();
System.gc();
}
}
void doSomeStuff()
{
try
{
sampleCppClass cppClass = new sampleCppClass();
/*
* do some stuff with Cpp obj
*/
} catch (Exception ex)
{
System.out.println(ex.getMessage());
}
}
我知道 System.gc() 和 System.runFinalization() 是不确定的 (Source-1, Source-2 and Source-3)。
doSomeStuff 中的 System.gc() 会被执行并释放对象吗?
稍后,主程序中的 System.gc() 运行并尝试释放同一个对象导致崩溃?如果确实如此,是否有办法证明这一点(logs/prints 以显示 gc 释放的对象的顺序)?
这样 post, explains causes of SIGABRT
因为我 运行 处于发布模式,所以我的 C++ 库没有任何 assert/abort。因此,我担心 double/multiple 考虑对象的空闲。
Can it so happen that the
System.gc()
indoSomeStuff()
gets executed & free's the obj.
是的,但也可能什么都不做。
Later on, the
System.gc()
in main runs & tries to free the same obj causing a crash?
没有。这是垃圾收集,而不是 C++ 销毁。每个对象只发生一次,或者永远不会发生。
就此代码而言,您的问题的根本原因是您的 gc()
和 runFinalization()
调用顺序错误。 runFinalization()
如果没有先前的 GC,则不执行任何操作。它执行仅由 GC 填充的终结器队列。
因此,当您全部执行两次时,只有第二次 runFinalization()
可以执行任何操作。这大概会在您的 SampleCPPClass
中执行一个终结器,它似乎有一个错误,显然是在本机代码中。
但是由于您还没有发布相关代码,因此无法进一步评论。