So I use System.gc() manually, is it really that bad ?

If I call System.gc() during map-changes. After unloading and loading is done, before the new map is on screen, I call System.gc().
Whats so bad about it, in a place when I’m expecting a short loading anyway ?

If you don’t care about the slight slow down, there is nothing bad at all.

Thats not the point, System.gc() doesn’t guarantee it will do a garbage collection:

Note the “suggests” and “expend effort” - it doesn’t really guarantee that GC will happen, though in practice it mostly does. The advice not to use it is based on it not being something you can rely on actually doing anything.

Kev

There is no single reason why you should never call it, but there are three issues which are related. First some people presume/rely on it always running, but there are garbage collectors that will simply ignore System.gc, such as those on a phone. JVM garbage collectors are also moving away from the simple ‘stop the world’ model (although they do need to stop it at certain points), and more towards running some of the work in parallel. Essentially when you call it, you don’t know what will happen!

The second issue is that it can be an indicator of bad code; such as excessive amounts of object creation. It is much better to solve the issue, in that example re-using objects or just creating less, rather then presuming System.gc will solve your problems.

The third issue is that it can reduce performance because you are asking the JVM to garbage collect more often, where it only ends up collecting a small proportion of objects. Typically leaving it up to the JVM to decide when to GC yields better performance (but not always better responsiveness).

To sum it up, generally it is seen that if you think you need to call System.gc then your program is probably flawed. However with the example you have given, I don’t see any real reason why you should not to call it.

Yeah well I don’t rely on it. It’s just a good moment for a garbage collection… and if it doesn’t happen, doesn’t matter
I would actually call it a mark for a moment in code when garbage collection would be nice

I don’t have memory issues or experience slow downs whenever the gc runs automatically or anything like that.
I just thought that this would be the perfect moment to gc, as all the objects and the map are being unload and load and stuff.

Seeing as the JRE can collect about a gig of garbage in under half a second on most machines now it’s hardly really worth doing it… just let it take care of itself I think. No harm in doing it between levels but… yeah, what’s the point, really…

Cas :slight_smile:

While we’re on the topic, what applications use the System.gc() call? :persecutioncomplex: When would you ever need that, seeing as it runs itself.

I say System.gc() is mostly used when you create a lot of objects and then, like changing levels, need to get rid of them fast because you’re about to create a lot of new objects. However remember that System.gc() doesn’t actually run the GC but expends effort toward garbage collection.

I wouldn’t give you a point in an exam if you answered a question like that :slight_smile:

Cas :slight_smile:

So does that mean I got 100%? :smiley:

Stopping a game for just a few frames is noticeable, so half a second is awful.

In theory yes, it is awful. In practice, you never collect even a tenth of that in one go, and in a strange twist, provided any pauses occur in a random and irregular and not-too-frequent fashion you can absolutely get away with delays of up to maybe a tenth of a second and no-one will bat an eyelid!

In practice, this means using -Xincgc, and your problems all vanish :slight_smile:

BTW last time I checked, Revenge of the Titans spends 0.1% of its entire execution time garbage collecting.

Cas :slight_smile:

What about G1?

My experiences with low latency audio, where pauses are far more of a concern, have so far been that -Xincgc (or -J-XX:+UseConcMarkSweepGC -J-XX:+CMSIncrementalMode, which I believe is equivalent these days) performs better than G1. YMMV :slight_smile:

G1 unfortunately crashes pretty frequently in JDK6 (at least it did about 4-5 months ago), though it’s fine in JDK7. I didn’t notice any significant different in GC activity for Revenge - but then, at 0.1% of total execution time, I was hardly likely to in the first place :slight_smile:

Escape analysis is finally properly turned on in JDK7 isn’t it?

Cas :slight_smile:

Well, I didn’t manage to crash it. However, when you’re doing audio with 256 or even 128 sample buffer you’re looking at over 170 or 350 fps. And no margin for missing it or it sounds like a train wreck. G1 just couldn’t cope with this when I tried, whereas Xincgc is pretty stable. Must try with 7 sometime.

Isn’t this now the same in 6 too? Seen a few posts that suggest this has been default since 6u23, but nothing I’d consider authoritative.

I didn’t think EA in 6 actually did that thing where it replaces heap allocs with stack allocs, though I might be wrong. Certainly cuts down on loads of short-lived garbage.

I’m curious as to why GC has any impact at all on audio…? Are you abusing IO design practices?

Cas :slight_smile:

I think HotSpot in 6 is now the same as 7(?), just with different default parameters.

Finally found something that looks authoritative - http://download.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html See comment under escape analysis about 6u23. See also that it seems to suggest neither 6 or 7 replace heap allocs with stack allocs, though do get rid of some object allocations altogether.

Same reason it has any impact on anything else - it stops the world! Not knowing quite what you mean by IO design practice, the audio libs in Praxis (which I’m finally in the process of getting out separately), in fact Praxis as a whole, is written around lock-free processing. This is the only way of doing decent low latency audio, but it doesn’t mean the GC can’t get in the way.

Drifting a bit OT here - sure the OP won’t mind … :persecutioncomplex:

well its all relevant to what GC can cause and how to handle it
can’t say that I knew -Xincgc before, or that I’m really sure what it does differently

Hm does stop-the-world actually stop all threads in the process, or just all Java threads, or just block allocs in Java threads? We use OpenAL to do our actual audio mixing, which carries on regardless of GC occurring or not (it has its own “native” mixing thread).

Cas :slight_smile: