Java Heap Sizing and Reading GC Logs
The Java Virtual Machine manages memory for your application through a garbage collector. Most production problems with memory come from a heap that is sized wrongly or from objects that are never released.
Set the heap with flags when you start the application:
bash java -Xms512m -Xmx1g -jar app.jar
-Xms sets the initial heap and -Xmx sets the maximum. Setting them to the same value avoids resizing pauses. In containers, recent JDK versions size the heap from the container limit when you pass -XX:MaxRAMPercentage=75.0.
To see what the collector is doing, enable unified GC logging:
bash java -Xlog:gc:file=gc.log:time -jar app.jar
Look for frequent full collections and pauses that keep growing, because both suggest the live set is close to the heap limit. Capture a heap dump on out-of-memory with -XX:+HeapDumpOnOutOfMemoryError, then open it in a tool such as Eclipse MAT to find the objects that hold the most memory.
For thread problems, jstack <pid prints a thread dump that shows blocked and waiting threads. Take two or three dumps a few seconds apart to separate real contention from brief waits. Always test heap changes under realistic load before deploying them.