我认为WeakReference引用对象将在调用System.gc()之后完成,但是我错了。
这里有两个测试用例,唯一的区别是WeakReference构造函数,第一个是新对象,而第二个使用引用,它们具有不同的性能,我不知道为什么...
弱引用对象,不会阻止其引用对象 进行定型,定型,然后回收。参考文献最弱 通常用于实现规范化的映射。
假设垃圾收集器在某个时间点确定 一个物体是弱的 可达的。到那时,它将原子清除所有弱引用。 该对象以及对其他任何弱可达对象的所有弱引用 通过一连串的强壮而柔软的物体可以从该物体到达 参考。同时它将声明所有以前的 弱可到达对象将被终结。同时或在某个时候 稍后它将排队那些新近清除的弱引用 在参考队列中注册。
package com.zeng.javaReference;
import org.junit.Test;
import java.lang.ref.WeakReference;
/**
* @author zeng
* @version 1.0.0
* @date 2020-05-11
*/
public class WeakReferenceTest {
@Test
public void weakRefRemoved() {
WeakReference<Apple> weakReference = new WeakReference<>(new Apple("green-apple"));
System.gc();
if (weakReference.get() == null) {
System.out.println("GC remove weakReference!");
} else {
System.out.println("weakReference still alive");
}
}
@Test
public void weakRefNotRemoved() {
Apple apple = new Apple("green-apple");
WeakReference<Apple> weakReference = new WeakReference<>(apple);
System.gc();
if (weakReference.get() == null) {
System.out.println("GC remove weakReference!");
} else {
System.out.println("weakReference still alive");
}
}
public static class Apple {
private String name;
public Apple(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("Apple: " + name + " finalized。");
}
@Override
public String toString() {
return "Apple{" +
"name='" + name + '\'' +
'}' + ", hashCode:" + this.hashCode();
}
}
}
答案 0 :(得分:0)
Unable to connect to Chrome debug port: 51656
FormatException: Unexpected character (at character 1)
<html>
^
#0 throwToolExit (package:flutter_tools/src/base/common.dart:14:3)
#1 ChromeLauncher._connect (package:flutter_tools/src/web/chrome.dart:251:9)
<asynchronous suspension>
#2 ChromeLauncher.launch (package:flutter_tools/src/web/chrome.dart:183:12)
<asynchronous suspension>
#3 ChromeDevice.startApp (package:flutter_tools/src/web/web_device.dart:142:46)
#4 _ResidentWebRunner.run.<anonymous closure>
(package:flutter_tools/src/build_runner/resident_web_runner.dart:443:29)
#5 _rootRunUnary (dart:async/zone.dart:1192:38)
#6 _CustomZone.runUnary (dart:async/zone.dart:1085:19)
#7 _FutureListener.handleValue (dart:async/future_impl.dart:141:18)
#8 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
#9 Future._propagateToListeners (dart:async/future_impl.dart:711:32)
#10 Future._completeWithValue (dart:async/future_impl.dart:526:5)
#11 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:36:15)
#12 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:298:13)
#13 _ResidentWebRunner._updateDevFS (package:flutter_tools/src/build_runner/resident_web_runner.dart)
#14 _rootRunUnary (dart:async/zone.dart:1192:38)
#15 _CustomZone.runUnary (dart:async/zone.dart:1085:19)
#16 _FutureListener.handleValue (dart:async/future_impl.dart:141:18)
#17 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
#18 Future._propagateToListeners (dart:async/future_impl.dart:711:32)
#19 Future._completeWithValue (dart:async/future_impl.dart:526:5)
#20 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:36:15)
#21 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:298:13)
#22 WebDevFS.update (package:flutter_tools/src/build_runner/devfs_web.dart)
#23 _rootRunUnary (dart:async/zone.dart:1192:38)
#24 _CustomZone.runUnary (dart:async/zone.dart:1085:19)
#25 _FutureListener.handleValue (dart:async/future_impl.dart:141:18)
#26 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
#27 Future._propagateToListeners (dart:async/future_impl.dart:711:32)
#28 Future._completeWithValue (dart:async/future_impl.dart:526:5)
#29 Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:556:7)
#30 _rootRun (dart:async/zone.dart:1184:13)
#31 _CustomZone.run (dart:async/zone.dart:1077:19)
#32 _CustomZone.runGuarded (dart:async/zone.dart:979:7)
#33 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1019:23)
#34 _microtaskLoop (dart:async/schedule_microtask.dart:43:21)
#35 _startMicrotaskLoop (dart:async/schedule_microtask.dart:52:5)
#36 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:118:13)
#37 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:169:5)
可能会也可能不会触发垃圾回收。
通过手动调用它,您只是在向JVM提供提示,但是天气会尊重它,这完全取决于Java运行时。 JVM是非常复杂的系统,不允许直接访问资源。
关于文档中的System.gc()
弱引用是指所引用的引用不足以使 要保留在内存中的对象。因此,弱引用可以让 垃圾收集器确定对象的可及性以及是否 有问题的对象应该保留在内存中。
再次决定收集物体的天气完全取决于收集器。
答案 1 :(得分:0)
这确实很有趣。
假设您使用的GC收集器在调用System.gc()
时实际上起到了某些作用,例如G1
,并且您没有禁用通过-XX:+DisableExplicitGC
对GC的显式调用,则有一个解释这,以某种方式。
weakRefNotRemoved
在理论上应与weakRefRemoved
相同。这与scope
和reachability
有关,有关此here的更多详细信息。
问题在于,在weakRefNotRemoved
中,apple
引用 之后,任何人都没有使用调用System.gc()
,因此在那时可以到达因此,从理论上讲,GC可以回收它,但是无论出于何种原因它都不会回收。我只能假定只有在存在实际内存压力时才触发此特殊路径。
为证明这一点,我们可以将代码稍作更改为:
public static void weakRefNotRemoved() {
Apple apple = new Apple("green-apple");
WeakReference<Apple> weakReference = new WeakReference<>(apple);
// explicitly set to null
apple = null;
System.gc();
if (weakReference.get() == null) {
System.out.println("GC remove weakReference!");
} else {
System.out.println("weakReference still alive");
}
}
现在,GC确实会清理它。通常,如果您试图证明一个观点,则最好在while循环中调用该观点,因为无法保证该循环将“抓住” that reference。同样是因为清除发生在asynchronous fashion中。像这样:
public static void weakRefNotRemoved() {
Apple apple = new Apple("green-apple");
WeakReference<Apple> weakReference = new WeakReference<>(apple);
apple = null;
while (weakReference.get() != null) {
System.out.println("weakReference still alive");
System.gc();
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
}
System.out.println("GC remove weakReference!");
}
获得这样的输出是完全合法的,例如:
weakReference still alive // zero or more of these messages
GC remove weakReference!