{ "type": "excalidraw", "version": 2, "source": "https://excalidraw.com", "elements": [ {"type": "text", "id": "title", "x": 160, "y": 15, "width": 780, "height": 45, "text": "JVM Memory Regions in a Container", "fontSize": 28, "fontFamily": 2, "textAlign": "center", "strokeColor": "#1971c2", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "text", "id": "subtitle", "x": 160, "y": 60, "width": 780, "height": 25, "text": "MaxRAMPercentage=75 only controls Heap — leaving 25% for 5 other regions", "fontSize": 14, "fontFamily": 1, "textAlign": "center", "strokeColor": "#666666", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "container", "x": 40, "y": 100, "width": 180, "height": 500, "strokeColor": "#1971c2", "backgroundColor": "#e7f5ff", "fillStyle": "solid", "roughness": 1, "opacity": 100, "angle": 0, "strokeWidth": 3}, {"type": "text", "id": "container-lbl", "x": 40, "y": 107, "width": 180, "height": 25, "text": "Container limit: 2 GB", "fontSize": 12, "fontFamily": 2, "textAlign": "center", "strokeColor": "#1971c2", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "heap-bar", "x": 60, "y": 135, "width": 140, "height": 200, "strokeColor": "#2f9e44", "backgroundColor": "#d3f9d8", "fillStyle": "solid", "roughness": 1, "opacity": 100, "angle": 0, "strokeWidth": 2}, {"type": "text", "id": "heap-bar-lbl", "x": 65, "y": 218, "width": 130, "height": 30, "text": "Heap\n~1.5 GB (75%)", "fontSize": 12, "fontFamily": 2, "textAlign": "center", "strokeColor": "#2f9e44", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "meta-bar", "x": 60, "y": 340, "width": 140, "height": 55, "strokeColor": "#e8590c", "backgroundColor": "#fff4e6", "fillStyle": "solid", "roughness": 1, "opacity": 100, "angle": 0, "strokeWidth": 2}, {"type": "text", "id": "meta-bar-lbl", "x": 65, "y": 354, "width": 130, "height": 25, "text": "Metaspace ~256 MB", "fontSize": 11, "fontFamily": 2, "textAlign": "center", "strokeColor": "#e8590c", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "threads-bar", "x": 60, "y": 400, "width": 140, "height": 45, "strokeColor": "#862e9c", "backgroundColor": "#f8f0fc", "fillStyle": "solid", "roughness": 1, "opacity": 100, "angle": 0, "strokeWidth": 2}, {"type": "text", "id": "threads-bar-lbl", "x": 65, "y": 413, "width": 130, "height": 25, "text": "Thread stacks ~100 MB", "fontSize": 10, "fontFamily": 2, "textAlign": "center", "strokeColor": "#862e9c", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "jit-bar", "x": 60, "y": 450, "width": 140, "height": 35, "strokeColor": "#c92a2a", "backgroundColor": "#fff5f5", "fillStyle": "solid", "roughness": 1, "opacity": 100, "angle": 0, "strokeWidth": 2}, {"type": "text", "id": "jit-bar-lbl", "x": 65, "y": 460, "width": 130, "height": 20, "text": "JIT Code Cache ~128 MB", "fontSize": 10, "fontFamily": 2, "textAlign": "center", "strokeColor": "#c92a2a", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "nio-bar", "x": 60, "y": 490, "width": 140, "height": 30, "strokeColor": "#e67700", "backgroundColor": "#fff9db", "fillStyle": "solid", "roughness": 1, "opacity": 100, "angle": 0, "strokeWidth": 2}, {"type": "text", "id": "nio-bar-lbl", "x": 65, "y": 498, "width": 130, "height": 20, "text": "Direct Buffers (Netty) ~50 MB", "fontSize": 9, "fontFamily": 2, "textAlign": "center", "strokeColor": "#e67700", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "gc-bar", "x": 60, "y": 525, "width": 140, "height": 30, "strokeColor": "#364fc7", "backgroundColor": "#edf2ff", "fillStyle": "solid", "roughness": 1, "opacity": 100, "angle": 0, "strokeWidth": 2}, {"type": "text", "id": "gc-bar-lbl", "x": 65, "y": 533, "width": 130, "height": 20, "text": "GC overhead ~50 MB", "fontSize": 9, "fontFamily": 2, "textAlign": "center", "strokeColor": "#364fc7", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "line", "id": "div1", "x": 220, "y": 100, "width": 0, "height": 500, "points": [[0,0],[0,500]], "strokeColor": "#cccccc", "roughness": 0, "opacity": 100, "angle": 0, "strokeWidth": 1}, {"type": "text", "id": "reg-title", "x": 260, "y": 100, "width": 680, "height": 25, "text": "Region", "fontSize": 13, "fontFamily": 2, "textAlign": "left", "strokeColor": "#333333", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "heap-row", "x": 240, "y": 130, "width": 700, "height": 75, "strokeColor": "#2f9e44", "backgroundColor": "#f4fdf6", "fillStyle": "solid", "roughness": 0, "opacity": 100, "angle": 0, "strokeWidth": 1}, {"type": "text", "id": "heap-row-txt", "x": 255, "y": 138, "width": 680, "height": 60, "text": "HEAP — controlled by -XX:MaxRAMPercentage=75.0\nWhere your objects live. GC runs here. The only region most people tune.\nTip: 75% is the right target — NOT 90%. You need room for the other 5 regions.", "fontSize": 12, "fontFamily": 1, "textAlign": "left", "strokeColor": "#2f9e44", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "meta-row", "x": 240, "y": 210, "width": 700, "height": 65, "strokeColor": "#e8590c", "backgroundColor": "#fffbf7", "fillStyle": "solid", "roughness": 0, "opacity": 100, "angle": 0, "strokeWidth": 1}, {"type": "text", "id": "meta-row-txt", "x": 255, "y": 218, "width": 680, "height": 55, "text": "METASPACE — controlled by -XX:MaxMetaspaceSize=256m\nClass metadata: method bytecodes, field descriptors, constant pools.\nGrows unbounded without a limit — can OOMKill silently in production.", "fontSize": 12, "fontFamily": 1, "textAlign": "left", "strokeColor": "#e8590c", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "threads-row", "x": 240, "y": 280, "width": 700, "height": 65, "strokeColor": "#862e9c", "backgroundColor": "#fdf8ff", "fillStyle": "solid", "roughness": 0, "opacity": 100, "angle": 0, "strokeWidth": 1}, {"type": "text", "id": "threads-row-txt", "x": 255, "y": 288, "width": 680, "height": 55, "text": "THREAD STACKS — 1 MB per platform thread × thread count\n200 platform threads = 200 MB off-heap stack space.\nQuarkus Virtual Threads (@RunOnVirtualThread) dramatically reduces this.", "fontSize": 12, "fontFamily": 1, "textAlign": "left", "strokeColor": "#862e9c", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "jit-row", "x": 240, "y": 350, "width": 700, "height": 65, "strokeColor": "#c92a2a", "backgroundColor": "#fff8f8", "fillStyle": "solid", "roughness": 0, "opacity": 100, "angle": 0, "strokeWidth": 1}, {"type": "text", "id": "jit-row-txt", "x": 255, "y": 358, "width": 680, "height": 55, "text": "JIT CODE CACHE — controlled by -XX:ReservedCodeCacheSize=256m\nNative machine code compiled by HotSpot JIT from bytecodes.\nProject Leyden AOT cache pre-populates this — faster warmup from first request.", "fontSize": 12, "fontFamily": 1, "textAlign": "left", "strokeColor": "#c92a2a", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "nio-row", "x": 240, "y": 420, "width": 700, "height": 65, "strokeColor": "#e67700", "backgroundColor": "#fffdf0", "fillStyle": "solid", "roughness": 0, "opacity": 100, "angle": 0, "strokeWidth": 1}, {"type": "text", "id": "nio-row-txt", "x": 255, "y": 428, "width": 680, "height": 55, "text": "DIRECT BYTEBUFFERS — not bounded by heap limit!\nNetty (used by Quarkus / Vert.x), NIO channels, Kafka clients allocate off-heap.\nAdd to your memory budget: container limit = heap + meta + threads + direct + 20%.", "fontSize": 12, "fontFamily": 1, "textAlign": "left", "strokeColor": "#e67700", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "gc-row", "x": 240, "y": 490, "width": 700, "height": 55, "strokeColor": "#364fc7", "backgroundColor": "#f8faff", "fillStyle": "solid", "roughness": 0, "opacity": 100, "angle": 0, "strokeWidth": 1}, {"type": "text", "id": "gc-row-txt", "x": 255, "y": 498, "width": 680, "height": 45, "text": "GC OVERHEAD — card tables, remembered sets, GC bookkeeping structures.\nG1GC uses more than ZGC. Typically 50-100 MB depending on heap size and GC choice.", "fontSize": 12, "fontFamily": 1, "textAlign": "left", "strokeColor": "#364fc7", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0}, {"type": "rectangle", "id": "formula-box", "x": 240, "y": 560, "width": 700, "height": 55, "strokeColor": "#1971c2", "backgroundColor": "#e7f5ff", "fillStyle": "solid", "roughness": 1, "opacity": 100, "angle": 0, "strokeWidth": 2}, {"type": "text", "id": "formula-txt", "x": 255, "y": 568, "width": 680, "height": 40, "text": "SIZING FORMULA: container_limit = (Heap/0.75) + MaxMetaspaceSize + (threads × 1MB) + DirectBuffers + GC_overhead\nMeasure with: jcmd VM.native_memory summary | kubectl top pod --containers", "fontSize": 12, "fontFamily": 2, "textAlign": "left", "strokeColor": "#1971c2", "backgroundColor": "transparent", "roughness": 0, "opacity": 100, "angle": 0} ], "appState": { "gridSize": null, "viewBackgroundColor": "#ffffff" } }