Note that there are some explanatory texts on larger screens.

plurals
  1. POWeird garbage production when instantiating Objects in Java
    primarykey
    data
    text
    <p>I am profiling the garbage behavior of <code>java.lang.String</code> and it looks like each time you instantiate a string <strong>for the first time inside any class</strong> it always generate garbage. Would anyone know why?</p> <pre><code>public abstract class AbstractTest { protected static String SERGIO = "sergio"; private String someValue; public void init() { this.someValue = new String(SERGIO); } } public class Test extends AbstractTest { private static String JULIA = "julia"; private Runtime runtime = Runtime.getRuntime(); private String anotherValue; private String yetAnother; private void gc() throws InterruptedException { System.gc(); Thread.sleep(100); } private long usedMemory() { return runtime.maxMemory() - runtime.freeMemory(); } public void test() throws Exception { gc(); this.anotherValue = new String(SERGIO); // a bunch of garbage is created! long usedMemory = usedMemory(); gc(); long usedMemoryAfterGC = usedMemory(); System.out.println("Collected: " + (usedMemory - usedMemoryAfterGC)); gc(); this.yetAnother = new String(JULIA); // no more garbage usedMemory = usedMemory(); gc(); usedMemoryAfterGC = usedMemory(); System.out.println("Collected: " + (usedMemory - usedMemoryAfterGC)); } public static void main(String[] args) throws Exception { Test t = new Test(); t.test(); } </code></pre> <p><strong>Output:</strong></p> <p>Collected: 704336<br/> Collected: 0</p> <p>That 's fine. First time it creates garbage, then subsequent instantiations produce no garbage.</p> <p>What is weird is when you force a string creation in the superclass, it still creates garbage in the subclass the first time you instantiate a String there:</p> <pre><code>public void test() throws Exception { gc(); init(); // creates a String in the superclass gc(); this.yetAnother = new String(JULIA); long usedMemory = usedMemory(); gc(); long usedMemoryAfterGC = usedMemory(); System.out.println("Collected: " + (usedMemory - usedMemoryAfterGC)); } </code></pre> <p><strong>Output:</strong></p> <p>Collected: 348648</p> <p>Any idea why?</p> <p>(By the way I am running this on MAC and JDK 1.6.0_37)</p> <p><strong>EDIT1:</strong> I changed the code slightly to make it clear that string internalization is not the culprit here, at least it does not look like it is.</p> <p><strong>EDIT2:</strong> If you change String to Object throughout the code, you get the same garbage so I guess it has to do with how object allocation through <em>new</em> happens in Java. The first time you allocate an object in a class you get the garbage. The second time you don't. Weird it is <em>per class</em>.</p> <p><strong>EDIT3:</strong> I wrote a <a href="http://mentablog.soliveirajr.com/2012/11/real-time-java-programming-without-gc/" rel="nofollow">blog article</a> where I talk about how to force a GC to profile your applications for garbage creation, like I am doing in the code above.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload