可達性算法中以GC Root對象為起點開始搜索。
什么是GC Root
對象
虛擬機棧中引用的對象
public class Rumenz{
public static void main(String[] args) {
Rumenz a = new Rumenz();
a = null;
}
}
a是棧幀中的本地變量,a就是
GC Root
,由於a=null
,a與new Rumenz()
對象斷開了鏈接,所以對象會被回收。
方法區類的靜態成員引用的對象
public class Rumenz{
public static Rumenz=r;
public static void main(String[] args){
Rumenz a=new Rumenz();
a.r=new Rumenz();
a=null;
}
}
棧幀中的本地變量
a=null
,由於a
斷開了與GC Root
對象(a對象)的聯系,所以a
對象會被回收。由於給Rumenz
的成員變量r
賦值了變量的引用,並且r
成員變量是靜態的,所以r
就是一個GC Root
對象,所以r
指向的對象不會被回收。
方法區常量引用的對象
public class Rumenz{
public static final Rumenz r=new Rumenz();
public static void main(String[] args){
Rumenz a=new Rumenz();
a=null;
}
}
常量
r
引用的對象不會因為a
引用的對象的回收而被回收。
本地方法棧中JNI引用的對象
JNIEXPORT void JNICALL Java_com_pecuyu_jnirefdemo_MainActivity_newStringNative(JNIEnv *env, jobject instance,jstring jmsg) {
...
// 緩存String的class
jclass jc = (*env)->FindClass(env, STRING_PATH);
}
本地方法就是一個 java 調用非 java 代碼的接口,該方法並非 Java 實現的,可能由 C 或 Python等其他語言實現的, Java 通過 JNI 來調用本地方法, 而本地方法是以庫文件的形式存放的(在 WINDOWS 平台上是 DLL 文件形式,在 UNIX 機器上是 SO 文件形式)。通過調用本地的庫文件的內部方法,使 JAVA 可以實現和本地機器的緊密聯系,調用系統級的各接口方法,
當調用 Java 方法時,虛擬機會創建一個棧楨並壓入 Java 棧,而當它調用的是本地方法時,虛擬機會保持 Java 棧不變,不會在 Java 棧禎中壓入新的禎,虛擬機只是簡單地動態連接並直接調用指定的本地方法。