Here is my very simple code :
class UpdateAlertActivity extends Activity { O o ; WeakReference<O> _o ; ArrayList<O> arr = new ArrayList<>(); static class O { private String l ; public O(String l) { this.l = l ; } } void test() { arr.clear(); Runtime.getRuntime().gc(); Log.i(LOG_TAG, "breakpoint"); } @Override protected void onResume() { super.onResume(); o = new O("hello"); arr.add(o); _o = new WeakReference<>(o); test(); } } As I clear array in test() method, I was excepting _o.get() to be null at my breakpoint, but it's not the case. When I see in the debbuger where o is held, it shows me only in the weak reference _o, while I thought weak reference are made to free their instance when there is no other strong reference on them...
I saw on StackOverflow that I missed calling GC, but calling it had no effect in my program as you can see.
EDIT : Even this super simple code does not work as excpected, it makes no sense...
O o = new O("lol"); WeakReference<O> _o = new WeakReference<>(o); Log.i(LOG_TAG, "1:" + _o.get().toString()); o = null ; Log.i(LOG_TAG, "2:" + _o.get().toString()); System.gc(); Log.i(LOG_TAG, "3:" + _o.get().toString()); // output not null here EDIT2 : I wanted the use of GC because I have, in another static class, an array called lastUpdates, which is filled with app updates sent by my server wia TCP, sometimes.
All my activities observes this lastUpdate array (by implementing Observer/Observable interface), and when it is changed, all are notified, and call a particular function onUpdate(ArrayList u) with the list of new arrived updates as a parameter. This function process the updates only if the activity is resumed (changing UI during activity sleep causes app to crash).
If the entiere app is "sleeping" (user is in device menu for example), I want only the first activity waking up to be able to process new updates.
For that, I created in my activity class a array pendingPersistentUpdates storing weak references of all updates that has been catch when activity was sleeping. When the first activity wakes up, the updates catch during app sleep time are still in lastUpdates array, so I expect the weak references stored in pendingPersistentUpdates activity prop to return the actual updates, so my activity can UI-process them, at onResume.
I was expecting this situation :
- An activity A run, an activity B is paused (behind activity A for example)
- App receives an update U. All activities (A and B) are notified. A process the update because it's running, as expected. B store this update in its
pendingPersistentUpdates, because it's paused. - A pause, user returns to B. At A pause, lastUpdates array is cleared, so the weak references of the updates in B
pendingPersistentUpdateswould return null - B resume, but
pendingPersistentUpdatesweak references are null (lastUpdates has been cleared), so U is not processed.
Though, as lastUpdate.clear() does not fire GC, B pendingPersistentUpdates updates still exist, and are processed a second time (behavior not desired)
Runtime.getRuntime().gc()may not always run the garbage collector