You could use JMX to collect the usage of heap memory at runtime.
Code Example:
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryType;
import java.lang.management.MemoryUsage;
for (MemoryPoolMXBean mpBean: ManagementFactory.getMemoryPoolMXBeans()) {
if (mpBean.getType() == MemoryType.HEAP) {
System.out.printf(
"Name: %s: %s\n",
mpBean.getName(), mpBean.getUsage()
);
}
}
Output Example:
Name: Eden Space: init = 6619136(6464K) used = 3754304(3666K) committed = 6619136(6464K) max = 186253312(181888K)
Name: Survivor Space: init = 786432(768K) used = 0(0K) committed = 786432(768K) max = 23265280(22720K)
Name: Tenured Gen: init = 16449536(16064K) used = 0(0K) committed = 16449536(16064K) max = 465567744(454656K)
If your have question about "Eden Space" or "Survivor Space", check out How is the java memory pool divided
Answer from Mike Lue on Stack OverflowYou could use JMX to collect the usage of heap memory at runtime.
Code Example:
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryType;
import java.lang.management.MemoryUsage;
for (MemoryPoolMXBean mpBean: ManagementFactory.getMemoryPoolMXBeans()) {
if (mpBean.getType() == MemoryType.HEAP) {
System.out.printf(
"Name: %s: %s\n",
mpBean.getName(), mpBean.getUsage()
);
}
}
Output Example:
Name: Eden Space: init = 6619136(6464K) used = 3754304(3666K) committed = 6619136(6464K) max = 186253312(181888K)
Name: Survivor Space: init = 786432(768K) used = 0(0K) committed = 786432(768K) max = 23265280(22720K)
Name: Tenured Gen: init = 16449536(16064K) used = 0(0K) committed = 16449536(16064K) max = 465567744(454656K)
If your have question about "Eden Space" or "Survivor Space", check out How is the java memory pool divided
maybe an useful update using Java 17 to 19: After several trials with getRuntime() and old/Eden/Survivor Space I came back to use getRuntime() which seem to be 'faithful' now:
With Java 17-19 therefore I propose to use the heap size functions of getRuntime():
Runtime env = Runtime.getRuntime();
System.out.println("Max Heap Size = maxMemory() = " + env.maxMemory()); //max heap size from -Xmx, i.e. is constant during runtime
System.out.println("Current Heap Size = totalMemory() = " + env.totalMemory()); //currently assigned heap
System.out.println("Available in Current Heap = freeMemory() = " + env.freeMemory()); //current heap will extend if no more freeMemory to a maximum of maxMemory
System.out.println("Currently Used Heap = " + (env.totalMemory()-env.freeMemory()) );
System.out.println("Unassigned Heap = " + (env.maxMemory()-env.totalMemory()));
System.out.println("Currently Totally Available Heap Space = "+ ((env.maxMemory()-env.totalMemory()) + env.freeMemory()) ); //available=unassigned + free
java - How to view the current heap size that an application is using? - Stack Overflow
java - Read maximum heap space at runtime - Stack Overflow
How can I find Java heap size and memory used (Linux)? - Stack Overflow
Command Line Tool for monitoring Java Heap - Unix & Linux Stack Exchange
Videos
Use this code:
// Get current size of heap in bytes.
long heapSize = Runtime.getRuntime().totalMemory();
// Get maximum size of heap in bytes. The heap cannot grow beyond this size.
// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();
// Get amount of free memory within the heap in bytes. This size will
// increase after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory();
It was useful to me to know it.
public class CheckHeapSize {
public static void main(String[] args) {
long heapSize = Runtime.getRuntime().totalMemory();
// Get maximum size of heap in bytes. The heap cannot grow beyond this size.// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();
// Get amount of free memory within the heap in bytes. This size will increase // after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory();
System.out.println("heap size: " + formatSize(heapSize));
System.out.println("heap max size: " + formatSize(heapMaxSize));
System.out.println("heap free size: " + formatSize(heapFreeSize));
}
public static String formatSize(long v) {
if (v < 1024) return v + " B";
int z = (63 - Long.numberOfLeadingZeros(v)) / 10;
return String.format("%.1f %sB", (double)v / (1L << (z*10)), " KMGTPE".charAt(z));
}
}
Each Java process has a pid, which you first need to find with the jps command.
Once you have the pid, you can use jstat -gc [insert-pid-here] to find statistics of the behavior of the garbage collected heap.
jstat -gccapacity [insert-pid-here]will present information about memory pool generation and space capabilities.jstat -gcutil [insert-pid-here]will present the utilization of each generation as a percentage of its capacity. Useful to get an at a glance view of usage.
See jstat docs on Oracle's site.
This command shows the configured heap sizes in bytes.
java -XX:+PrintFlagsFinal -version | grep HeapSize
It works on Amazon AMI on EC2 as well.
if you are trying to compare to something like jconsole or jvisualvm with the main window displaying 'total heap usage' I found out that by adding 'used eden space' and 'used ps old generation space' I got the equivalent of what that graph shows in the aforementioned programs -- that's what I tend to go on now.
The entries under Heap Usage: are listing the various partitioned memory pools in the JVM, along with their max size, used and free space. You could just add up the various used: values, that should give you a sensible value for the total memory usage, although there may be some JVM overhead that's not accounted for in the listed pools.
What's wrong with MXBeans? The implementation is not so hard.
I've used something like that :
List<GarbageCollectorMXBean> gcList = ManagementFactory.getGarbageCollectorMXBeans();
for(GarbageCollectorMXBean tmpGC : gcList){
System.out.println("\nName: " + tmpGC.getName());
System.out.println("Collection count: " + tmpGC.getCollectionCount());
System.out.println("Collection time: " + tmpGC.getCollectionTime());
System.out.println("Memory Pools: ");
String[] memoryPoolNames = tmpGC.getMemoryPoolNames();
for(String mpnTmp : memoryPoolNames){
System.out.println("\t" + mpnTmp);
}
}
System.out.println( "Memory Pools Info" );
List<MemoryPoolMXBean> memoryList = ManagementFactory.getMemoryPoolMXBeans();
for(MemoryPoolMXBean tmpMem : memoryList){
System.out.println("\nName: " + tmpMem.getName());
System.out.println("Usage: " + tmpMem.getUsage());
System.out.println("Collection Usage: " + tmpMem.getCollectionUsage());
System.out.println("Peak Usage: " + tmpMem.getPeakUsage());
System.out.println("Type: " + tmpMem.getType());
System.out.println("Memory Manager Names: ") ;
String[] memManagerNames = tmpMem.getMemoryManagerNames();
for(String mmnTmp : memManagerNames){
System.out.println("\t" + mmnTmp);
}
System.out.println("\n");
}
MemoryUsage mu =ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
MemoryUsage muNH =ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
System.out.println(
"Init :"+mu.getInit()+
"\nMax :"+mu.getMax()+
"\nUsed :"+mu.getUsed()+
"\nCommited :"+mu.getCommitted()+
"\nInit NH :"+muNH.getInit()+
"\nMax NH :"+muNH.getMax()+
"\nUsed NH:"+muNH.getUsed()+
"\nCommited NH:"+muNH.getCommitted());
You can launch the JVM with options to control runtime output of this kind of information.
See the java tool documentation.
For example to ouput to the console:
java -verbose:gc
or to output to file:
java -Xloggc:your.log.file
With either of these options, the JVM logs every GC event while the VM is running (not just when it exits).