29 * @author Martin Buchholz |
29 * @author Martin Buchholz |
30 */ |
30 */ |
31 |
31 |
32 import static java.util.concurrent.TimeUnit.MILLISECONDS; |
32 import static java.util.concurrent.TimeUnit.MILLISECONDS; |
33 import static java.util.concurrent.TimeUnit.NANOSECONDS; |
33 import static java.util.concurrent.TimeUnit.NANOSECONDS; |
34 import static java.util.concurrent.TimeUnit.SECONDS; |
|
35 |
34 |
36 import java.io.File; |
35 import java.io.File; |
37 import java.io.FileOutputStream; |
36 import java.io.FileOutputStream; |
38 import java.io.IOException; |
37 import java.io.IOException; |
39 import java.io.InputStream; |
38 import java.io.InputStream; |
40 import java.io.InputStreamReader; |
39 import java.io.InputStreamReader; |
41 import java.io.OutputStream; |
40 import java.io.OutputStream; |
42 import java.io.PrintStream; |
41 import java.io.PrintStream; |
43 import java.io.Reader; |
42 import java.io.Reader; |
|
43 import java.lang.ref.ReferenceQueue; |
44 import java.lang.ref.WeakReference; |
44 import java.lang.ref.WeakReference; |
45 import java.util.concurrent.BlockingQueue; |
45 import java.util.concurrent.BlockingQueue; |
46 import java.util.concurrent.Callable; |
46 import java.util.concurrent.Callable; |
47 import java.util.concurrent.CountDownLatch; |
47 import java.util.concurrent.CountDownLatch; |
48 import java.util.concurrent.CyclicBarrier; |
48 import java.util.concurrent.CyclicBarrier; |
123 return result; |
123 return result; |
124 } |
124 } |
125 |
125 |
126 /** No guarantees, but effective in practice. */ |
126 /** No guarantees, but effective in practice. */ |
127 private static void forceFullGc() { |
127 private static void forceFullGc() { |
128 CountDownLatch finalizeDone = new CountDownLatch(1); |
128 long timeoutMillis = 1000L; |
129 WeakReference<?> ref = new WeakReference<Object>(new Object() { |
129 CountDownLatch finalized = new CountDownLatch(1); |
130 protected void finalize() { finalizeDone.countDown(); }}); |
130 ReferenceQueue<Object> queue = new ReferenceQueue<>(); |
|
131 WeakReference<Object> ref = new WeakReference<>( |
|
132 new Object() { protected void finalize() { finalized.countDown(); }}, |
|
133 queue); |
131 try { |
134 try { |
132 for (int i = 0; i < 10; i++) { |
135 for (int tries = 3; tries--> 0; ) { |
133 System.gc(); |
136 System.gc(); |
134 if (finalizeDone.await(1L, SECONDS) && ref.get() == null) { |
137 if (finalized.await(timeoutMillis, MILLISECONDS) |
|
138 && queue.remove(timeoutMillis) != null |
|
139 && ref.get() == null) { |
135 System.runFinalization(); // try to pick up stragglers |
140 System.runFinalization(); // try to pick up stragglers |
136 return; |
141 return; |
137 } |
142 } |
|
143 timeoutMillis *= 4; |
138 } |
144 } |
139 } catch (InterruptedException unexpected) { |
145 } catch (InterruptedException unexpected) { |
140 throw new AssertionError("unexpected InterruptedException"); |
146 throw new AssertionError("unexpected InterruptedException"); |
141 } |
147 } |
142 throw new AssertionError("failed to do a \"full\" gc"); |
148 throw new AssertionError("failed to do a \"full\" gc"); |