GC causing massive delay

@Riven

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… :slight_smile:

I found this an enlightening discussion, and I would like to learn a bit more about the inner workings of garbage collection in the JVM. Do you guys have suggestions for “further reading”?

I do know about (and am reading) Oracle’s GC tutorials and Oracle’s info about HotSpot GC.

[quote=“ralphchapin,post:21,topic:43345”]
You really have to let the idea of costly merges of free-lists go. Inserting objects between arrays really won’t matter, due to the nature of the GC algorithms, as explained earlier, they copy alive objects and arrays to a new memory block, meanig that there simply are no free lists to merge.

[quote=“ralphchapin,post:21,topic:43345”]
They actually require the GC to do a lot of work, because it has to trace extremely deep object graphs of reachable objects, which is what will slow everything down tremendously for every single garbage collection, even when all objects reside in Eden.

Just test it yourself, it only takes 1 minute to test (and invalidate) your C-heap inspired theories.

@Riven: You’re right. I have seen big-array problems;whether that was an old GC or whether I need a fancier test to reproduce it I don’t know.

I ran the thing on an antique machine with a 250MB heap and a single core. I added an actual object (an 8 character string, created with “new”–just using quotes gave me the same results as using null). Using the object slows down the ArrayList so it’s only about half again as fast as the linked list and can only hold twice as much before the out-of-memory error. (Without it, my results were like yours, scaled down by a factor of 8. I printed a message and time every 131072 (1024X128) lines.

The results between the two lists were amazingly similar. The ArrayList needed 20 milliseconds between rows and the LinkedList 30. (Its a slow machine, and the smallest measurable time interval is 10 milliseconds.) About every ten to 12 messages, the time needed spiked to 500 to 2000 ms, getting larger as the program ran. I looked to me like the program was doing repeated garbage collections. These would be needed for the ArrayList, but in the case of the LinkedList, until the last one there was plenty of free memory and, at no point, was any memory freed!

As you noted, arrays take less time in gc, even when there is array space to be collected and no LinkedList space to be collected.

I’m not sure what to make of all this. It seems to slow down code that doesn’t free large arrays without helping those that do. But it is interesting.

You really have to drop the concept of collecting garbage and freeing memory. That’s not what a garbage collector does :slight_smile:

Think of it as a room with gadgets, toys, empty pizza boxes and dead rats. Mom comes in, takes handful of toys and gadgets, puts them in brother’s room, then locks your room. Whatever filth was there is out of reach and can be completely ignored. (if we go further, the analogy breaks apart… let’s say uncle bob effortlessly atomizes whatever is left in your room, and pumps it in your 3d printer reservoir, for you to print new pizza boxes, which attract dead rats, aight!)

That has to be the best analogy I’ve ever read. ;D

[quote=“Grunnt,post:22,topic:43345”]
Java Garbage Collection Distilled
Understanding Garbage Collection
G1: One Garbage Collector To Rule Them All
Garbage First Garbage Collector Tuning

Very nice explanation. Thanks!

So if the gc does not free garbage collected objects, what happens to the collected garbage? Does it just stay there infinitely until program closes?

Great, thanks Spasi! I’m reading it now, it’s good background info.

It’s a block of memory containing meaningless ones and zeroes. Eventually the block of memory will be overwritten with meaningful ones and zeros. (new objects)

Thanks!