For load test
If you want to run a load test in a JUnit test case and get maximum memory consumption or GC count as a Java variable, the way to do it doesn't seem to be.
For memory consumption of whole Java VM
If you want to run some tests and measure memory consumption of the whole Java VM, you can use Runtime#totalMemory()
and Runtime#freeMemory()
like this *1:
static long initialMemoryConsumption; @BeforeAll static void recordInitialMemoryConsumption() { initialMemoryConsumption = getMemoryConsumption(); } @AfterAll static void measureWholeMemoryConsumption() { System.out.println(getMemoryConsumption() - initialMemoryConsumption); } static long getMemoryConsumption() { Runtime runtime = Runtime.getRuntime(); runtime.gc(); return runtime.totalMemory() - runtime.freeMemory(); }
For memory consumption of an object
If you want to measure rough memory consumption of a specific object in a test (for example, validate memory consumption is and not , or validate all the caches are invalidated), you can serialize the object into a byte array and measure the length of it.
static int getMemoryConsumption(Serializable obj) throws IOException { try ( ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); ) { out.writeObject(obj); out.flush(); byte[] bytes = bos.toByteArray(); return bytes.length; } } @Test void memoryConsumptionTest() throws IOException { ... assertTrue(getMemoryConsumption(someObject) < 500); }
- You cannot use
Runtime#totalMemory()
andRuntime#freeMemory()
for this purpose, because the whole memory consumption of Java VM reduces in a test case (memory consumption could seem like a minus value). - The measured object should implement the
Serializable
interface. If it doesn't, you have to add the interface at runtime with the Java instrumentation API and a library like Javassist *2. - The actual length of the byte array (
< 500
in the above example) should be measured in the test environment before writing a test case.