I want to understand how WeakReference works with a simple example. There are suspicions that in my program WeakReference in a separate thread becomes a strong link.
Tried to do as follows:
public class TestWeak { private static Object object; private static WeakReference<Object> wr; private static Runnable runnable = new Runnable() { @Override public void run() { try { Object object4 = object; System.out.println("Object4: " + object4); Object object5 = wr.get(); System.out.println("Object5: " + object5); System.out.println("Setting object to null"); object = null; System.out.println("Running Garbage Collection..."); Runtime.getRuntime().gc(); // run GC to collect the object Thread.sleep( 1000 ); System.out.println("Setting object4 to null"); object4 = null; System.out.println("Running Garbage Collection..."); Runtime.getRuntime().gc(); // run GC to collect the object Thread.sleep( 1000 ); System.out.println("Setting object5 to null"); object5 = null; System.out.println("Running Garbage Collection..."); Runtime.getRuntime().gc(); // run GC to collect the object } catch (Exception e) { e.printStackTrace(); } } }; public static void main(String[] args) throws InterruptedException { object = new Object(); // Create a new weak reference that refers to the given object and is registered with this queue. wr = new WeakReference<Object>(object); // , rq); System.out.println("Object: " + object); Object object2 = wr.get(); System.out.println("Object2: " + object2); Object object3 = object2; System.out.println("Object3: " + object3); // start a new thread that will remove all references of object ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); service.schedule(runnable, 2, TimeUnit.SECONDS); System.out.println("Wait ...."); boolean flag = true; while (flag) { if (wr.get() == null) { System.out.println("Reference: " + wr); System.out.println("Object is no longer referenced."); flag = false; } } service.shutdown(); } }
Console:
Object: java.lang.Object@7852e922 Object2: java.lang.Object@7852e922 Object3: java.lang.Object@7852e922 Wait .... Object4: java.lang.Object@7852e922 Object5: java.lang.Object@7852e922 Setting object to null Running Garbage Collection... Setting object4 to null Running Garbage Collection... Setting object5 to null Running Garbage Collection... Reference: java.lang.ref.WeakReference@3d4eac69 Object is no longer referenced.
Why does GC remove an object only after object5 (weak link) is set to null?
UPDATE:
If you comment out this line:
// object5 = null;
You will never see in the console:
Object is no longer referenced.
Our overseas friends say that GC works as it pleases. https://stackoverflow.com/questions/29784793/java-weakreference-inside-thread
But in my opinion, this example does not affect the different workings of the GC, and the problem is the incorrect operation / use of the WeakReference.
PS I also tried to overflow memory in parallel. Memory overflowed, but did not see the necessary line in the console.
System.gc()
is not a decree. This is just a "tip" to start garbage collection, the final decision on launching GC remains with the JVM. There is always a chance that the call toSystem.gc()
will be ignored. - fori1ton