fork download
  1. import java.util.function.BiFunction;
  2.  
  3. import java.lang.ref.PhantomReference;
  4. import java.lang.ref.WeakReference;
  5. import java.lang.ref.ReferenceQueue;
  6. import java.lang.ref.Reference;
  7.  
  8. class ReferencesTest {
  9. private static SomeObject resurrectedObject = null;
  10. private static int nextAttemptToKillCounter = 0;
  11.  
  12. private static void referenceTest(
  13. BiFunction<SomeObject, ReferenceQueue<? super SomeObject>,
  14. Reference<? extends SomeObject>> constr, int delay)
  15. ReferenceQueue<SomeObject> rq = new ReferenceQueue<>();
  16. SomeObject strongRef = new SomeObject();
  17. Reference<? extends SomeObject> ref = constr.apply(strongRef, rq);
  18.  
  19. // delete the strong reference
  20. strongRef = null;
  21. // try to trigger the GC
  22. System.gc();
  23. while (true) {
  24. // try to poll something from the RQ
  25. Reference<? extends SomeObject> pulledRef = rq.poll();
  26. System.out.printf("poll(): %s\n", pulledRef);
  27. if (pulledRef != null) {
  28. System.out.printf("ref.get(): %s\n",
  29. ref.get());
  30. System.out.printf("resurrectedObject = %s\n",
  31. resurrectedObject);
  32. break;
  33. }
  34.  
  35. if (resurrectedObject != null
  36. && nextAttemptToKillCounter == 0) {
  37. System.out.println(
  38. "*exterminate the resurrected object*");
  39. resurrectedObject = null;
  40. // try to trigger the GC
  41. System.gc();
  42. }
  43. if (nextAttemptToKillCounter > 0) {
  44. System.out.printf(
  45. "*next attempt to kill in %d steps*\n",
  46. nextAttemptToKillCounter);
  47. nextAttemptToKillCounter--;
  48. }
  49.  
  50. Thread.sleep(delay);
  51. }
  52. }
  53.  
  54. public static void main(String[] args) throws InterruptedException {
  55. System.out.println("**phantom reference test**");
  56. referenceTest(PhantomReference::new, 250);
  57.  
  58. System.out.println("\n**weak reference test**");
  59. referenceTest(WeakReference::new, 250);
  60. }
  61.  
  62. private static class SomeObject {
  63. @Override
  64. public void finalize() throws Throwable {
  65. System.out.println("*at the finalize method*");
  66. resurrectedObject = this;
  67. nextAttemptToKillCounter = 10;
  68. System.out.println("*resurrection*");
  69. }
  70. }
  71. }
Success #stdin #stdout 0.1s 35236KB
stdin
Standard input is empty
stdout
**phantom reference test**
poll(): null
*at the finalize method*
*resurrection*
poll(): null
*next attempt to kill in 10 steps*
poll(): null
*next attempt to kill in 9 steps*
poll(): null
*next attempt to kill in 8 steps*
poll(): null
*next attempt to kill in 7 steps*
poll(): null
*next attempt to kill in 6 steps*
poll(): null
*next attempt to kill in 5 steps*
poll(): null
*next attempt to kill in 4 steps*
poll(): null
*next attempt to kill in 3 steps*
poll(): null
*next attempt to kill in 2 steps*
poll(): null
*next attempt to kill in 1 steps*
poll(): null
*exterminate the resurrected object*
poll(): java.lang.ref.PhantomReference@e9e54c2
ref.get(): null
resurrectedObject = null

**weak reference test**
poll(): null
*at the finalize method*
*resurrection*
poll(): java.lang.ref.WeakReference@eed1f14
ref.get(): null
resurrectedObject = ReferencesTest$SomeObject@7229724f