I added a DebugController (code below) to try to figure out what is using all the memory in 3.1.0.
3.1.0 is using 67 MB more maching memory than 2.33.2. However, it’s not clear where that is being used, as the Java heap is only 10 MB bigger, and the Java non-heap is only 15 MB bigger, so where is the extra 42 MB being used?
Results:
Using gae-datastore 2.33.2 :
=== JVM Heap ===
Used: 46 MB
Committed: 92 MB
Max: 92 MB
=== JVM Non-Heap (Metaspace, Code Cache, etc.) ===
Used: 75 MB
Committed: 75 MB
=== JVM Memory Pools ===
Metaspace [Non-heap memory] used=51 MB committed=52 MB
Tenured Gen [Heap memory] used=33 MB committed=64 MB
Eden Space [Heap memory] used=12 MB committed=25 MB
Survivor Space [Heap memory] used=0 MB committed=3 MB
Compressed Class Space [Non-heap memory] used=10 MB committed=10 MB
CodeCache [Non-heap memory] used=12 MB committed=12 MB
=== Process (OS view) ===
Committed virtual memory: 1431 MB
=== Machine Memory ===
Total: 384 MB
Used: 298 MB
Free: 85 MB
Using gae-datastore 3.1.0 :
=== JVM Heap ===
Used: 55 MB
Committed: 92 MB
Max: 92 MB
=== JVM Non-Heap (Metaspace, Code Cache, etc.) ===
Used: 90 MB
Committed: 91 MB
=== JVM Memory Pools ===
Metaspace [Non-heap memory] used=64 MB committed=64 MB
Tenured Gen [Heap memory] used=34 MB committed=64 MB
Eden Space [Heap memory] used=21 MB committed=25 MB
Survivor Space [Heap memory] used=0 MB committed=3 MB
Compressed Class Space [Non-heap memory] used=13 MB committed=13 MB
CodeCache [Non-heap memory] used=12 MB committed=12 MB
=== Process (OS view) ===
Committed virtual memory: 1441 MB
=== Machine Memory ===
Total: 384 MB
Used: 365 MB
Free: 18 MB
The DebugController code that outputs the above results:
import com.sun.management.OperatingSystemMXBean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.util.List;
@RestController
public class DebugController {
private static final long MB = 1024L * 1024L;
@GetMapping(value = "/debug/memory", produces = "text/plain;charset=UTF-8")
public String getMemoryUsage() {
StringBuilder sb = new StringBuilder();
// --- JVM Heap & Non-Heap ---
MemoryMXBean memBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heap = memBean.getHeapMemoryUsage();
MemoryUsage nonHeap = memBean.getNonHeapMemoryUsage();
sb.append("=== JVM Heap ===\n");
sb.append(String.format(" Used: %d MB%n", heap.getUsed() / MB));
sb.append(String.format(" Committed: %d MB%n", heap.getCommitted() / MB));
sb.append(String.format(" Max: %d MB%n", heap.getMax() / MB));
sb.append("\n=== JVM Non-Heap (Metaspace, Code Cache, etc.) ===\n");
sb.append(String.format(" Used: %d MB%n", nonHeap.getUsed() / MB));
sb.append(String.format(" Committed: %d MB%n", nonHeap.getCommitted() / MB));
// --- Memory Pools (what is using heap/non-heap) ---
sb.append("\n=== JVM Memory Pools ===\n");
List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean pool : pools) {
MemoryUsage usage = pool.getUsage();
if (usage == null) continue;
sb.append(String.format(" %-40s [%s] used=%d MB committed=%d MB%n",
pool.getName(),
pool.getType(),
usage.getUsed() / MB,
usage.getCommitted() / MB));
}
// --- OS / Process memory ---
OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
long processCommitted = osBean.getCommittedVirtualMemorySize();
long machineTotal = osBean.getTotalMemorySize();
long machineFree = osBean.getFreeMemorySize();
long machineUsed = machineTotal - machineFree;
sb.append("\n=== Process (OS view) ===\n");
sb.append(String.format(" Committed virtual memory: %d MB%n", processCommitted / MB));
sb.append("\n=== Machine Memory ===\n");
sb.append(String.format(" Total: %d MB%n", machineTotal / MB));
sb.append(String.format(" Used: %d MB%n", machineUsed / MB));
sb.append(String.format(" Free: %d MB%n", machineFree / MB));
return sb.toString();
}
}