The full picture
- Fault taxonomy: zero-fill (first malloc touch), COW break (post-fork write), page-cache hit mapping (minor), swap-in / file read-in (major), and the invalid access that actually is a bug → SIGSEGV. Same trap, five meanings — the kernel disambiguates via the VMA (memory-region metadata).
- Why 'allocated' isn't 'paid for': calloc of 1GB is instant; the cost arrives as ~262k minor faults as you touch it. Pre-touching (
-XX:+AlwaysPreTouch) moves that cost to startup — why low-latency JVMs pay it there instead of during requests. - Reading the metrics:
ps/pidstatmin_flt/maj_flt,vmstatsi/so. Minor fault storms = churny allocation or COW after fork (Redis snapshot!); any sustained majfl on a latency-critical service = swapping or cold file access — act now. - Swap policy for services: the modern stance is not 'swap off' dogma but 'swap ≠ latency path' — many operators run swap off or tiny for JVM fleets because a GC walking swapped heap pages is catastrophic; K8s historically required swap off for accounting sanity.