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.

  • And they are right .... - Athari
  • Maybe! But the answer to the question: Why, then, commenting on just one line in the example above causes the GC to refuse to process the WeakReference? - They dont have! - Pavel B
  • Please provide the code in question and specify which line to comment out in order to cause the GC to refuse to process the WeakReference. - fori1ton
  • one
    In general, the answer is simple: GC works as it pleases him, and the call to 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 to System.gc() will be ignored. - fori1ton
  • Why minus the question? Why is he so bad? - Pavel B

1 answer 1

You are mistaken, considering that object5 is a weak reference to an object. object5 is a strong link. There is only one weak link in your program - wr .