Memory management in JVM HotSpot:
Another desirable garbage collector feature is fragmentation restriction. When memory for garbage objects is freed up, free space may appear in small pieces in various areas, there will not be enough space in any adjacent area that will be used to allocate a large object. The approach to removing fragmentation is called compaction, discussed among the various garbage collector designs below.
Memory management in JVM HotSpot (PDF format).
This behavior can be highly dependent on the particular implementation of the garbage collection. For instance:
Parallel Mark Compact
- Stop world
- The heap is divided into pieces of a fixed size (> 2kb now, most likely, will increase or will be subject to ergonomics)
- Chunk is a unit of summing live data.
- Parallel label
- Record live data addresses in an external bitmap
- Find current real-time data size
- Find tight pieces, i.e. those that are (almost) full of living objects
I made this sample (with abusive String concatenation to use more memory):
public class TestFreeMemory { static void allocateSomeMemory(){ long[][] array = new long[400][400]; } public static void main(String ... args){ Runtime rt = Runtime.getRuntime(); allocateSomeMemory(); // once we leave, our array is not reachable anymore System.out.println("Free Memory (Before GC): " + rt.freeMemory()); rt.gc(); System.out.println("Free Memory (After GC): " + rt.freeMemory()); String a = new String("A"); for(int i = 0; i < 100; i++){ a+="B"; } System.out.println("Free Memory (After String Creation): " + rt.freeMemory()); // Less free memory expected. } }
Exit
Free memory (before GC): 3751800
Free memory (after GC): 5036104
Free memory (after creating the line): 5012048
If I use a relatively small number of iterations in a loop (say 10), the extra space does not appear in freeMemory() , and I would get something like the following:
Free memory (before GC): 3751800
Free memory (after GC): 5036040
Free memory (after creating the line): 5036040
source share