I am having a hard time trying to understand what is going on with Strings and memory management in Android (Java).
To simplify, have a look at this simple piece of code:
public void createArray(){ String s = ""; String foo = "foo"; String lorem = "Lorem ipsum ad his scripta blandit partiendo, eum fastidii accumsan euripidis in, eum liber hendrerit an."; ArrayList<Item> array = new ArrayList<Item>(); for( int i=0; i<20000; i++ ){ s = foo.replace("foo", lorem); array.add( new Item(s) ); } System.gc(); } private class Item{ String name; public Item(String name){ this.name = name; } } If executed, createArray will allocate more than 5Mb in memory. Even with the System.gc() instruction, memory won't be deallocated after the loop.
Now, if we replace s = foo.replace("foo", lorem); with s = lorem;, allocated memory will only increase by 0.5Mb.
I need to understand what is going on to improve my application's performance.
Can anybody explain how should I replace Strings in a case like this? And why is System.gc() not deallocating memory?
Thanks.
UPDATE:
Thanks for the answers, now I understand that System.gc() is only a hint.
To clarify the other question (the important one):
How can I dynamically generate 20000 Strings ("foo1", "foo2"... "foo20000") add them to the ArrayList and do not run out of memory? If this 20000 strings were static they wouldn't allocate more than 0.5Mb in memory. Besides, if s = foo.replace("foo", lorem) creates a brand new String, why my function allocates 5Mb which is 10 times more memory? Shouldn't be around 1Mb?
(I am already thinking in a workaround but I want to be sure there is no way to generate the strings dynamically without using this huge amount of memory)
array = null. That should free up references for GC.