在GC G1调研过程中,渡娘找到一个观点,在以下代码中
Object obj=new Object();
obj.equals(new Object);
通过obj取得对应的对象,如obj.equals(new Object());而这样obj对后边的Object的一个强引用,只有当obj这个引用被释放之后,对象才会被释放掉,这也是我们经常用到的编码形式。
观点被提出,但未找到官方出处,也没有明确解答,逻辑上无法理解,为何会在方法层面,修改了底层的引用概念,于是自己验证了一下。代码如下:
import static java.lang.Thread.sleep;
public class GCTestApplication {
public int nRecord = 0;
@Override
protected void finalize() throws Throwable {
System.out.println("GCTestApplication 被回收了"+nRecord);
}
public static void main(String[] args) {
GCTestApplication test = new GCTestApplication();
test.nRecord = 1;
if(test.equals(new GCTestApplication())){
System.out.println("equals");
} else {
System.out.println("not equals");
}
for(int i =0;i<3;i++){
try {
sleep(500);
System.out.println(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.gc();
for(int i =0;i<3;i++){
try {
sleep(500);
System.out.println(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
test = null;
System.gc();
}
}
打印结果如下:
not equals
0
1
2
GCTestApplication 被回收了0
0
1
2
GCTestApplication 被回收了1
得到new Object(), 先释放,test后释放的结论。又或者如果相等的情况下被强引用,于是继承了equals方法再测试,
public class GCTestApplication {
@Override
public boolean equals(Object obj) {
return true;
}
public int nRecord = 0;
@Override
protected void finalize() throws Throwable {
System.out.println("GCTestApplication 被回收了"+nRecord);
}
public static void main(String[] args) {
GCTestApplication test = new GCTestApplication();
test.nRecord = 1;
if(test.equals(new GCTestApplication())){
System.out.println("equals");
} else {
System.out.println("not equals");
}
for(int i =0;i<3;i++){
try {
sleep(500);
System.out.println(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.gc();
for(int i =0;i<3;i++){
try {
sleep(500);
System.out.println(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
test = null;
System.gc();
}
}
打印结果还是相同。
equals
0
1
2
GCTestApplication 被回收了0
0
1
2
GCTestApplication 被回收了1
观点被否定。