2

Possible Duplicate:
How can I avoid garbage collection delays in Java games? (Best Practices)

Java's GC pause is a killer. Often the time, the application doesn't have the memory leak. At some point, it may pause for ~1 second for every 1G memory allocation.

What are good Java coding practices to help Java GC?

One example, since null object becomes eligible for garbage collection, so it is a good idea to explicitly set an object to null e.g. object = null.

Community
  • 1
  • 1
stones333
  • 8,588
  • 1
  • 25
  • 27
  • 3
    "Null object"? I don't think that's a thing... – Oliver Charlesworth Jan 18 '13 at 16:58
  • @HighCore You realize that C# is also a garbage collected language, right? – KyleM Jan 18 '13 at 17:01
  • One approach is to avoid unnecessary garbage: avoid dynamic creation of objects and use pools of reusable objects. – Victor Sorokin Jan 18 '13 at 17:02
  • What I mean is set an object null to help GC collect it. For example, an application creates a context object for a user request (Tomcat/JBoss). If set context object to null, does it help Java GC and make it more efficient? – stones333 Jan 18 '13 at 17:03
  • @KyleM the difference is that .Net actually works =) – Federico Berasategui Jan 18 '13 at 17:10
  • @stones333 Yes setting it to null would make it eligible for garbage collection, as long as there are no other references to that object. – KyleM Jan 18 '13 at 17:21
  • 1
    @HighCore I've never had problems with Java's garbage collection, or with C# garbage collection. I view complaints by those who have as their own problems of poor memory management...It's also possible to request garbage collection System.gc() or something like that. Potentially, you could do so when you know your program won't be especially busy. – KyleM Jan 18 '13 at 17:24

3 Answers3

4

In general to help GC you should avoid of unreasonable memory usage. Simple advices could be:

1) Do not produce new objects, where it is not needed. For example do not use constructions like String test = new String("blabla");. If it possible, reuse old objects (it belongs to immutable objects mainly).

2) Do not declare fields in classes, where they are used only inside methods; i.e. make them local variables.

3) Avoid of using object wrappers under primitive types. I.e. use int instead of Integer, boolean instead of Boolean, if you really do not need to store in them null values. Also for example, where it is possible, for memory economy, do not use ArrayList, use simple Java arrays of primitive types (not Integer[], but int[]).

Andremoniy
  • 34,031
  • 20
  • 135
  • 241
  • 1
    Yes, that is good. What else? One more thing I can think of is to use StringBuilder.append() instead of String concatenation to avoid creating unnecessary objects. – stones333 Jan 18 '13 at 17:11
  • String concatenation uses StringBuilder.append(). Disassemble some code with javap -c and see for yourself. – David Conrad Jan 18 '13 at 17:27
  • @DavidConrad really? Hm, in JSL7 said, that when you concatenate two strings - you produce new `String` object. – Andremoniy Jan 18 '13 at 17:30
  • @Andremoniy Yes, when you concatenate two strings, you produce a new string object. By constructing a StringBuilder, calling its append method with each of the strings, and then calling its toString method to get the resulting string. As I said, write a trivial program, compile it, and then disassemble it with `javap -c` and you will see that even though you did not mention StringBuilder in your source code, the java compiler still emits code that uses a StringBuilder to concatenate the strings. – David Conrad Jan 18 '13 at 17:46
3

The single best thing that you can do to minimize GC pauses is to properly size your heap.

If you know that your program never uses more than 1Gb of live objects, then it's pointless to pass -Xms4096m. That will actually increase your GC pauses, because the JVM will leave garbage around until it absolutely has to clear it.

Similarly, if you know that you have very few long-lived objects, you can usually benefit by increasing the size of the young generation relative to the tenured generation (for Sun JVMs).

The only thing that you can really do, coding-wise, is to move large objects off-heap. But that's unlikely to be useful for most applications.

parsifal
  • 1,645
  • 9
  • 6
  • Understood. As a JBoss web application, we can not dictator how users behavior. The requests could be large in size or come in faster rate . Here is one real life example (http://stackoverflow.com/questions/6530045/useconcmarksweepgc-strange-happening) – stones333 Jan 19 '13 at 17:49
0

Objects that are allocated and not immediately released get moved into the tenured heap space. Tenured memory is the most expensive to collect. Avoid churning through long lived objects should help with GC pauses.

Steve Kuo
  • 61,876
  • 75
  • 195
  • 257