I haven’t tried this recently, and when I last had the problem I was trying to do something else completely. Still, I’ve heard of enough other people with the problem that I doubt it’s gone away. I am beginning to wonder if my ArrayList Add test does much to demonstrate it.
I would suggest adding a new object rather than null to the array. What you’ve got will, if I still understand ArrayList, fill memory consecutively with arrays, each 50% larger than the previous. All but the last two will be freed, and the next to last one will usually be freed. When allocations hits the end of available memory, they can easily go back to the start and reuse what’s there. Adding actual objects will put those objects between each array. Now the GC has some real work to do. I can’t guarantee a proper out-of-memory exception with 90% of memory still free, but you should see something of interest.
It seems to me that fragmentation still must be an issue. To allocate space for a large array, you need a bunch of contiguous memory blocks with nothing in them. With allocated bits of memory scatter through them, that means a lot of copying.
LinkedLists are slow memory hogs, but they only ask the GC to do a tiny amount of work at a time.
And its probably time for me to go read the tuning doc…