jarrodhroberson
12/10/2013 - 7:11 AM

Trust the Garbage Collector

Trust the Garbage Collector

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * See what it looks like in JVisualVM
 * https://www.evernote.com/shard/s17/sh/430c9fd1-203a-45da-9194-b7cb20dbdf0f/4f67d91157f68db32e43badd9d806f1c/deep/0/Java-VisualVM.png
 */
public class TrustTheGarbageCollector
{
    public static void main(final String[] args)
    {
        // this causes the most degenerate behavior for expansion of the List
        final List<String> strings = new ArrayList<String>(1) {
            @Override
            public boolean add(final String s)
            {
                // this keeps the references for a short time
                // and bounds the list but it does it in the worst way
                // possible memory efficiency wise
                if (this.size() >= 1024 * 100) { this.remove(0); }
                return super.add(s);
            }
        };
        final Random rnd = new Random(System.currentTimeMillis());
        final long max = Long.MAX_VALUE;
        long lfm = Runtime.getRuntime().freeMemory();
        for (int l = 0; l < max; l++)
        {
            // this causes the most degenerate behavior possible
            // it causes as many re-allocations of the backing Array as possible
            final StringBuilder sb = new StringBuilder(1);
            // this makes sure the lengths are not the same so it doesn't allocate in
            // contiguous blocks
            for (int i = 0; i < 1024 * 1024 * rnd.nextInt(1024); i++)
            {
                sb.append(rnd.nextInt(Character.MAX_VALUE));
            }
            // create a String, and store it away to hold memory out
            final String s = sb.toString();
            strings.add(s);
            final long fm = Runtime.getRuntime().freeMemory();
            if (lfm < fm)
            {
                System.out.format("Memory Usage + %d out of %d", fm, Runtime.getRuntime().totalMemory());
                System.out.println();
            }
            else
            {
                System.out.format("Memory Usage - %d out of %d", fm, Runtime.getRuntime().totalMemory());
                System.out.println();
            }
            lfm = fm;
        }
    }
}