垃圾回收不只是"把没用的对象清掉"。真正要回答清楚 JVM GC,需要先说明三个问题:怎么判断垃圾、怎么回收垃圾、为什么要把堆分代。
判断垃圾主要靠可达性分析;回收垃圾常见算法有标记清除、标记整理、复制算法;分代回收则是基于大多数对象"朝生夕死"的经验,把新对象和老对象分开处理。
三种基础垃圾回收算法
#mermaid-svg-lTuz3LkoeuvF5b3J{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lTuz3LkoeuvF5b3J .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lTuz3LkoeuvF5b3J .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lTuz3LkoeuvF5b3J .error-icon{fill:#552222;}#mermaid-svg-lTuz3LkoeuvF5b3J .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lTuz3LkoeuvF5b3J .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lTuz3LkoeuvF5b3J .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lTuz3LkoeuvF5b3J .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lTuz3LkoeuvF5b3J .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lTuz3LkoeuvF5b3J .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lTuz3LkoeuvF5b3J .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lTuz3LkoeuvF5b3J .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lTuz3LkoeuvF5b3J .marker.cross{stroke:#333333;}#mermaid-svg-lTuz3LkoeuvF5b3J svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lTuz3LkoeuvF5b3J p{margin:0;}#mermaid-svg-lTuz3LkoeuvF5b3J .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-lTuz3LkoeuvF5b3J .cluster-label text{fill:#333;}#mermaid-svg-lTuz3LkoeuvF5b3J .cluster-label span{color:#333;}#mermaid-svg-lTuz3LkoeuvF5b3J .cluster-label span p{background-color:transparent;}#mermaid-svg-lTuz3LkoeuvF5b3J .label text,#mermaid-svg-lTuz3LkoeuvF5b3J span{fill:#333;color:#333;}#mermaid-svg-lTuz3LkoeuvF5b3J .node rect,#mermaid-svg-lTuz3LkoeuvF5b3J .node circle,#mermaid-svg-lTuz3LkoeuvF5b3J .node ellipse,#mermaid-svg-lTuz3LkoeuvF5b3J .node polygon,#mermaid-svg-lTuz3LkoeuvF5b3J .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lTuz3LkoeuvF5b3J .rough-node .label text,#mermaid-svg-lTuz3LkoeuvF5b3J .node .label text,#mermaid-svg-lTuz3LkoeuvF5b3J .image-shape .label,#mermaid-svg-lTuz3LkoeuvF5b3J .icon-shape .label{text-anchor:middle;}#mermaid-svg-lTuz3LkoeuvF5b3J .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-lTuz3LkoeuvF5b3J .rough-node .label,#mermaid-svg-lTuz3LkoeuvF5b3J .node .label,#mermaid-svg-lTuz3LkoeuvF5b3J .image-shape .label,#mermaid-svg-lTuz3LkoeuvF5b3J .icon-shape .label{text-align:center;}#mermaid-svg-lTuz3LkoeuvF5b3J .node.clickable{cursor:pointer;}#mermaid-svg-lTuz3LkoeuvF5b3J .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-lTuz3LkoeuvF5b3J .arrowheadPath{fill:#333333;}#mermaid-svg-lTuz3LkoeuvF5b3J .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-lTuz3LkoeuvF5b3J .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-lTuz3LkoeuvF5b3J .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lTuz3LkoeuvF5b3J .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lTuz3LkoeuvF5b3J .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lTuz3LkoeuvF5b3J .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-lTuz3LkoeuvF5b3J .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-lTuz3LkoeuvF5b3J .cluster text{fill:#333;}#mermaid-svg-lTuz3LkoeuvF5b3J .cluster span{color:#333;}#mermaid-svg-lTuz3LkoeuvF5b3J div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-lTuz3LkoeuvF5b3J .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lTuz3LkoeuvF5b3J rect.text{fill:none;stroke-width:0;}#mermaid-svg-lTuz3LkoeuvF5b3J .icon-shape,#mermaid-svg-lTuz3LkoeuvF5b3J .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lTuz3LkoeuvF5b3J .icon-shape p,#mermaid-svg-lTuz3LkoeuvF5b3J .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-lTuz3LkoeuvF5b3J .icon-shape .label rect,#mermaid-svg-lTuz3LkoeuvF5b3J .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lTuz3LkoeuvF5b3J .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-lTuz3LkoeuvF5b3J .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-lTuz3LkoeuvF5b3J :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 垃圾回收算法
标记清除
标记整理
复制算法
这三种算法不是具体垃圾回收器,而是垃圾回收器背后的基本策略。
标记清除算法
标记清除分两步:先标记需要回收的对象,再清除这些对象占用的内存。
#mermaid-svg-zz1hj0bh5wnsXzz8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zz1hj0bh5wnsXzz8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zz1hj0bh5wnsXzz8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zz1hj0bh5wnsXzz8 .error-icon{fill:#552222;}#mermaid-svg-zz1hj0bh5wnsXzz8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zz1hj0bh5wnsXzz8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zz1hj0bh5wnsXzz8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zz1hj0bh5wnsXzz8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zz1hj0bh5wnsXzz8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zz1hj0bh5wnsXzz8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zz1hj0bh5wnsXzz8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zz1hj0bh5wnsXzz8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zz1hj0bh5wnsXzz8 .marker.cross{stroke:#333333;}#mermaid-svg-zz1hj0bh5wnsXzz8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zz1hj0bh5wnsXzz8 p{margin:0;}#mermaid-svg-zz1hj0bh5wnsXzz8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-zz1hj0bh5wnsXzz8 .cluster-label text{fill:#333;}#mermaid-svg-zz1hj0bh5wnsXzz8 .cluster-label span{color:#333;}#mermaid-svg-zz1hj0bh5wnsXzz8 .cluster-label span p{background-color:transparent;}#mermaid-svg-zz1hj0bh5wnsXzz8 .label text,#mermaid-svg-zz1hj0bh5wnsXzz8 span{fill:#333;color:#333;}#mermaid-svg-zz1hj0bh5wnsXzz8 .node rect,#mermaid-svg-zz1hj0bh5wnsXzz8 .node circle,#mermaid-svg-zz1hj0bh5wnsXzz8 .node ellipse,#mermaid-svg-zz1hj0bh5wnsXzz8 .node polygon,#mermaid-svg-zz1hj0bh5wnsXzz8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zz1hj0bh5wnsXzz8 .rough-node .label text,#mermaid-svg-zz1hj0bh5wnsXzz8 .node .label text,#mermaid-svg-zz1hj0bh5wnsXzz8 .image-shape .label,#mermaid-svg-zz1hj0bh5wnsXzz8 .icon-shape .label{text-anchor:middle;}#mermaid-svg-zz1hj0bh5wnsXzz8 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-zz1hj0bh5wnsXzz8 .rough-node .label,#mermaid-svg-zz1hj0bh5wnsXzz8 .node .label,#mermaid-svg-zz1hj0bh5wnsXzz8 .image-shape .label,#mermaid-svg-zz1hj0bh5wnsXzz8 .icon-shape .label{text-align:center;}#mermaid-svg-zz1hj0bh5wnsXzz8 .node.clickable{cursor:pointer;}#mermaid-svg-zz1hj0bh5wnsXzz8 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-zz1hj0bh5wnsXzz8 .arrowheadPath{fill:#333333;}#mermaid-svg-zz1hj0bh5wnsXzz8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zz1hj0bh5wnsXzz8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zz1hj0bh5wnsXzz8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zz1hj0bh5wnsXzz8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zz1hj0bh5wnsXzz8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zz1hj0bh5wnsXzz8 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-zz1hj0bh5wnsXzz8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zz1hj0bh5wnsXzz8 .cluster text{fill:#333;}#mermaid-svg-zz1hj0bh5wnsXzz8 .cluster span{color:#333;}#mermaid-svg-zz1hj0bh5wnsXzz8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zz1hj0bh5wnsXzz8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zz1hj0bh5wnsXzz8 rect.text{fill:none;stroke-width:0;}#mermaid-svg-zz1hj0bh5wnsXzz8 .icon-shape,#mermaid-svg-zz1hj0bh5wnsXzz8 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zz1hj0bh5wnsXzz8 .icon-shape p,#mermaid-svg-zz1hj0bh5wnsXzz8 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-zz1hj0bh5wnsXzz8 .icon-shape .label rect,#mermaid-svg-zz1hj0bh5wnsXzz8 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zz1hj0bh5wnsXzz8 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-zz1hj0bh5wnsXzz8 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-zz1hj0bh5wnsXzz8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 开始 GC
从 GC Roots 做可达性分析
标记不可达对象
清除不可达对象
释放内存
它的优点是流程简单,标记和清除速度相对直接。缺点也很明显:清除后会产生内存碎片。
#mermaid-svg-g2rKCmnir6fEPgW4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-g2rKCmnir6fEPgW4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-g2rKCmnir6fEPgW4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-g2rKCmnir6fEPgW4 .error-icon{fill:#552222;}#mermaid-svg-g2rKCmnir6fEPgW4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-g2rKCmnir6fEPgW4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-g2rKCmnir6fEPgW4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-g2rKCmnir6fEPgW4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-g2rKCmnir6fEPgW4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-g2rKCmnir6fEPgW4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-g2rKCmnir6fEPgW4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-g2rKCmnir6fEPgW4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-g2rKCmnir6fEPgW4 .marker.cross{stroke:#333333;}#mermaid-svg-g2rKCmnir6fEPgW4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-g2rKCmnir6fEPgW4 p{margin:0;}#mermaid-svg-g2rKCmnir6fEPgW4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-g2rKCmnir6fEPgW4 .cluster-label text{fill:#333;}#mermaid-svg-g2rKCmnir6fEPgW4 .cluster-label span{color:#333;}#mermaid-svg-g2rKCmnir6fEPgW4 .cluster-label span p{background-color:transparent;}#mermaid-svg-g2rKCmnir6fEPgW4 .label text,#mermaid-svg-g2rKCmnir6fEPgW4 span{fill:#333;color:#333;}#mermaid-svg-g2rKCmnir6fEPgW4 .node rect,#mermaid-svg-g2rKCmnir6fEPgW4 .node circle,#mermaid-svg-g2rKCmnir6fEPgW4 .node ellipse,#mermaid-svg-g2rKCmnir6fEPgW4 .node polygon,#mermaid-svg-g2rKCmnir6fEPgW4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-g2rKCmnir6fEPgW4 .rough-node .label text,#mermaid-svg-g2rKCmnir6fEPgW4 .node .label text,#mermaid-svg-g2rKCmnir6fEPgW4 .image-shape .label,#mermaid-svg-g2rKCmnir6fEPgW4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-g2rKCmnir6fEPgW4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-g2rKCmnir6fEPgW4 .rough-node .label,#mermaid-svg-g2rKCmnir6fEPgW4 .node .label,#mermaid-svg-g2rKCmnir6fEPgW4 .image-shape .label,#mermaid-svg-g2rKCmnir6fEPgW4 .icon-shape .label{text-align:center;}#mermaid-svg-g2rKCmnir6fEPgW4 .node.clickable{cursor:pointer;}#mermaid-svg-g2rKCmnir6fEPgW4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-g2rKCmnir6fEPgW4 .arrowheadPath{fill:#333333;}#mermaid-svg-g2rKCmnir6fEPgW4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-g2rKCmnir6fEPgW4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-g2rKCmnir6fEPgW4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-g2rKCmnir6fEPgW4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-g2rKCmnir6fEPgW4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-g2rKCmnir6fEPgW4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-g2rKCmnir6fEPgW4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-g2rKCmnir6fEPgW4 .cluster text{fill:#333;}#mermaid-svg-g2rKCmnir6fEPgW4 .cluster span{color:#333;}#mermaid-svg-g2rKCmnir6fEPgW4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-g2rKCmnir6fEPgW4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-g2rKCmnir6fEPgW4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-g2rKCmnir6fEPgW4 .icon-shape,#mermaid-svg-g2rKCmnir6fEPgW4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-g2rKCmnir6fEPgW4 .icon-shape p,#mermaid-svg-g2rKCmnir6fEPgW4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-g2rKCmnir6fEPgW4 .icon-shape .label rect,#mermaid-svg-g2rKCmnir6fEPgW4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-g2rKCmnir6fEPgW4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-g2rKCmnir6fEPgW4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-g2rKCmnir6fEPgW4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 回收前
存活对象和垃圾对象交错
清除垃圾对象
产生不连续空闲空间
碎片多了以后,即使总空闲内存不少,也可能找不到连续空间分配大对象。
| 优点 | 缺点 |
|---|---|
| 实现简单,清理速度较快 | 容易产生内存碎片 |
| 不需要移动大量对象 | 大对象分配可能受影响 |
标记整理算法
标记整理也会先标记对象,但清理时不是直接把垃圾对象挖掉,而是把存活对象向一端移动,再清理边界外的空间。
#mermaid-svg-SfBtV25EcyMxiEs5{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-SfBtV25EcyMxiEs5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SfBtV25EcyMxiEs5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SfBtV25EcyMxiEs5 .error-icon{fill:#552222;}#mermaid-svg-SfBtV25EcyMxiEs5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SfBtV25EcyMxiEs5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SfBtV25EcyMxiEs5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SfBtV25EcyMxiEs5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SfBtV25EcyMxiEs5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SfBtV25EcyMxiEs5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SfBtV25EcyMxiEs5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SfBtV25EcyMxiEs5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SfBtV25EcyMxiEs5 .marker.cross{stroke:#333333;}#mermaid-svg-SfBtV25EcyMxiEs5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SfBtV25EcyMxiEs5 p{margin:0;}#mermaid-svg-SfBtV25EcyMxiEs5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-SfBtV25EcyMxiEs5 .cluster-label text{fill:#333;}#mermaid-svg-SfBtV25EcyMxiEs5 .cluster-label span{color:#333;}#mermaid-svg-SfBtV25EcyMxiEs5 .cluster-label span p{background-color:transparent;}#mermaid-svg-SfBtV25EcyMxiEs5 .label text,#mermaid-svg-SfBtV25EcyMxiEs5 span{fill:#333;color:#333;}#mermaid-svg-SfBtV25EcyMxiEs5 .node rect,#mermaid-svg-SfBtV25EcyMxiEs5 .node circle,#mermaid-svg-SfBtV25EcyMxiEs5 .node ellipse,#mermaid-svg-SfBtV25EcyMxiEs5 .node polygon,#mermaid-svg-SfBtV25EcyMxiEs5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SfBtV25EcyMxiEs5 .rough-node .label text,#mermaid-svg-SfBtV25EcyMxiEs5 .node .label text,#mermaid-svg-SfBtV25EcyMxiEs5 .image-shape .label,#mermaid-svg-SfBtV25EcyMxiEs5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-SfBtV25EcyMxiEs5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-SfBtV25EcyMxiEs5 .rough-node .label,#mermaid-svg-SfBtV25EcyMxiEs5 .node .label,#mermaid-svg-SfBtV25EcyMxiEs5 .image-shape .label,#mermaid-svg-SfBtV25EcyMxiEs5 .icon-shape .label{text-align:center;}#mermaid-svg-SfBtV25EcyMxiEs5 .node.clickable{cursor:pointer;}#mermaid-svg-SfBtV25EcyMxiEs5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-SfBtV25EcyMxiEs5 .arrowheadPath{fill:#333333;}#mermaid-svg-SfBtV25EcyMxiEs5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-SfBtV25EcyMxiEs5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-SfBtV25EcyMxiEs5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SfBtV25EcyMxiEs5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-SfBtV25EcyMxiEs5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SfBtV25EcyMxiEs5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-SfBtV25EcyMxiEs5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-SfBtV25EcyMxiEs5 .cluster text{fill:#333;}#mermaid-svg-SfBtV25EcyMxiEs5 .cluster span{color:#333;}#mermaid-svg-SfBtV25EcyMxiEs5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-SfBtV25EcyMxiEs5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-SfBtV25EcyMxiEs5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-SfBtV25EcyMxiEs5 .icon-shape,#mermaid-svg-SfBtV25EcyMxiEs5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SfBtV25EcyMxiEs5 .icon-shape p,#mermaid-svg-SfBtV25EcyMxiEs5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-SfBtV25EcyMxiEs5 .icon-shape .label rect,#mermaid-svg-SfBtV25EcyMxiEs5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SfBtV25EcyMxiEs5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-SfBtV25EcyMxiEs5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-SfBtV25EcyMxiEs5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 开始 GC
标记存活对象
移动存活对象到一端
清理边界外空间
得到连续可用内存
标记整理解决了内存碎片问题,但对象移动会带来额外成本。
| 优点 | 缺点 |
|---|---|
| 回收后内存连续 | 移动对象成本较高 |
| 适合老年代 | 停顿时间可能变长 |
老年代中对象存活率通常较高,如果使用复制算法,会复制大量对象,成本较高。因此老年代收集器经常使用标记清除或标记整理思路。
复制算法
复制算法把内存分成两块,每次只使用其中一块。GC 时把存活对象复制到另一块,然后把原来的区域整体清空。
#mermaid-svg-c75MWFKIg0cfAhQd{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-c75MWFKIg0cfAhQd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-c75MWFKIg0cfAhQd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-c75MWFKIg0cfAhQd .error-icon{fill:#552222;}#mermaid-svg-c75MWFKIg0cfAhQd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-c75MWFKIg0cfAhQd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-c75MWFKIg0cfAhQd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-c75MWFKIg0cfAhQd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-c75MWFKIg0cfAhQd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-c75MWFKIg0cfAhQd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-c75MWFKIg0cfAhQd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-c75MWFKIg0cfAhQd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-c75MWFKIg0cfAhQd .marker.cross{stroke:#333333;}#mermaid-svg-c75MWFKIg0cfAhQd svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-c75MWFKIg0cfAhQd p{margin:0;}#mermaid-svg-c75MWFKIg0cfAhQd .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-c75MWFKIg0cfAhQd .cluster-label text{fill:#333;}#mermaid-svg-c75MWFKIg0cfAhQd .cluster-label span{color:#333;}#mermaid-svg-c75MWFKIg0cfAhQd .cluster-label span p{background-color:transparent;}#mermaid-svg-c75MWFKIg0cfAhQd .label text,#mermaid-svg-c75MWFKIg0cfAhQd span{fill:#333;color:#333;}#mermaid-svg-c75MWFKIg0cfAhQd .node rect,#mermaid-svg-c75MWFKIg0cfAhQd .node circle,#mermaid-svg-c75MWFKIg0cfAhQd .node ellipse,#mermaid-svg-c75MWFKIg0cfAhQd .node polygon,#mermaid-svg-c75MWFKIg0cfAhQd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-c75MWFKIg0cfAhQd .rough-node .label text,#mermaid-svg-c75MWFKIg0cfAhQd .node .label text,#mermaid-svg-c75MWFKIg0cfAhQd .image-shape .label,#mermaid-svg-c75MWFKIg0cfAhQd .icon-shape .label{text-anchor:middle;}#mermaid-svg-c75MWFKIg0cfAhQd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-c75MWFKIg0cfAhQd .rough-node .label,#mermaid-svg-c75MWFKIg0cfAhQd .node .label,#mermaid-svg-c75MWFKIg0cfAhQd .image-shape .label,#mermaid-svg-c75MWFKIg0cfAhQd .icon-shape .label{text-align:center;}#mermaid-svg-c75MWFKIg0cfAhQd .node.clickable{cursor:pointer;}#mermaid-svg-c75MWFKIg0cfAhQd .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-c75MWFKIg0cfAhQd .arrowheadPath{fill:#333333;}#mermaid-svg-c75MWFKIg0cfAhQd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-c75MWFKIg0cfAhQd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-c75MWFKIg0cfAhQd .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-c75MWFKIg0cfAhQd .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-c75MWFKIg0cfAhQd .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-c75MWFKIg0cfAhQd .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-c75MWFKIg0cfAhQd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-c75MWFKIg0cfAhQd .cluster text{fill:#333;}#mermaid-svg-c75MWFKIg0cfAhQd .cluster span{color:#333;}#mermaid-svg-c75MWFKIg0cfAhQd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-c75MWFKIg0cfAhQd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-c75MWFKIg0cfAhQd rect.text{fill:none;stroke-width:0;}#mermaid-svg-c75MWFKIg0cfAhQd .icon-shape,#mermaid-svg-c75MWFKIg0cfAhQd .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-c75MWFKIg0cfAhQd .icon-shape p,#mermaid-svg-c75MWFKIg0cfAhQd .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-c75MWFKIg0cfAhQd .icon-shape .label rect,#mermaid-svg-c75MWFKIg0cfAhQd .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-c75MWFKIg0cfAhQd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-c75MWFKIg0cfAhQd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-c75MWFKIg0cfAhQd :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} From 区使用中
发生 GC
复制存活对象到 To 区
清空 From 区
From 和 To 角色交换
复制算法的优势是清理后没有碎片,而且在垃圾对象多、存活对象少时效率很高。缺点是需要额外空间,内存利用率会下降。
| 优点 | 缺点 |
|---|---|
| 没有内存碎片 | 需要额外空闲区域 |
| 存活对象少时效率高 | 存活对象多时复制成本高 |
新生代对象大多存活时间短,所以复制算法非常适合新生代。
为什么要分代回收
JVM 分代回收基于一个经验判断:大多数对象生命周期很短,少数对象会存活很久。
#mermaid-svg-DjOhiYDh5nKrhBSf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DjOhiYDh5nKrhBSf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DjOhiYDh5nKrhBSf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DjOhiYDh5nKrhBSf .error-icon{fill:#552222;}#mermaid-svg-DjOhiYDh5nKrhBSf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DjOhiYDh5nKrhBSf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DjOhiYDh5nKrhBSf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DjOhiYDh5nKrhBSf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DjOhiYDh5nKrhBSf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DjOhiYDh5nKrhBSf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DjOhiYDh5nKrhBSf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DjOhiYDh5nKrhBSf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DjOhiYDh5nKrhBSf .marker.cross{stroke:#333333;}#mermaid-svg-DjOhiYDh5nKrhBSf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DjOhiYDh5nKrhBSf p{margin:0;}#mermaid-svg-DjOhiYDh5nKrhBSf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-DjOhiYDh5nKrhBSf .cluster-label text{fill:#333;}#mermaid-svg-DjOhiYDh5nKrhBSf .cluster-label span{color:#333;}#mermaid-svg-DjOhiYDh5nKrhBSf .cluster-label span p{background-color:transparent;}#mermaid-svg-DjOhiYDh5nKrhBSf .label text,#mermaid-svg-DjOhiYDh5nKrhBSf span{fill:#333;color:#333;}#mermaid-svg-DjOhiYDh5nKrhBSf .node rect,#mermaid-svg-DjOhiYDh5nKrhBSf .node circle,#mermaid-svg-DjOhiYDh5nKrhBSf .node ellipse,#mermaid-svg-DjOhiYDh5nKrhBSf .node polygon,#mermaid-svg-DjOhiYDh5nKrhBSf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DjOhiYDh5nKrhBSf .rough-node .label text,#mermaid-svg-DjOhiYDh5nKrhBSf .node .label text,#mermaid-svg-DjOhiYDh5nKrhBSf .image-shape .label,#mermaid-svg-DjOhiYDh5nKrhBSf .icon-shape .label{text-anchor:middle;}#mermaid-svg-DjOhiYDh5nKrhBSf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DjOhiYDh5nKrhBSf .rough-node .label,#mermaid-svg-DjOhiYDh5nKrhBSf .node .label,#mermaid-svg-DjOhiYDh5nKrhBSf .image-shape .label,#mermaid-svg-DjOhiYDh5nKrhBSf .icon-shape .label{text-align:center;}#mermaid-svg-DjOhiYDh5nKrhBSf .node.clickable{cursor:pointer;}#mermaid-svg-DjOhiYDh5nKrhBSf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DjOhiYDh5nKrhBSf .arrowheadPath{fill:#333333;}#mermaid-svg-DjOhiYDh5nKrhBSf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DjOhiYDh5nKrhBSf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DjOhiYDh5nKrhBSf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DjOhiYDh5nKrhBSf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DjOhiYDh5nKrhBSf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DjOhiYDh5nKrhBSf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DjOhiYDh5nKrhBSf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DjOhiYDh5nKrhBSf .cluster text{fill:#333;}#mermaid-svg-DjOhiYDh5nKrhBSf .cluster span{color:#333;}#mermaid-svg-DjOhiYDh5nKrhBSf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DjOhiYDh5nKrhBSf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DjOhiYDh5nKrhBSf rect.text{fill:none;stroke-width:0;}#mermaid-svg-DjOhiYDh5nKrhBSf .icon-shape,#mermaid-svg-DjOhiYDh5nKrhBSf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DjOhiYDh5nKrhBSf .icon-shape p,#mermaid-svg-DjOhiYDh5nKrhBSf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DjOhiYDh5nKrhBSf .icon-shape .label rect,#mermaid-svg-DjOhiYDh5nKrhBSf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DjOhiYDh5nKrhBSf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DjOhiYDh5nKrhBSf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DjOhiYDh5nKrhBSf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 大多数对象
少数对象
新创建对象
是否很快变成垃圾
在新生代被回收
多次存活后晋升老年代
如果不分代,所有对象混在一起回收,每次 GC 都要扫描更大范围,成本会很高。分代后,新生代可以频繁、快速回收;老年代可以用更适合高存活率对象的算法。
堆的分代结构
传统分代模型中,堆主要分为新生代和老年代。新生代又分为 Eden、Survivor From、Survivor To。
#mermaid-svg-ReqvnxRwvhdsNHWs{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ReqvnxRwvhdsNHWs .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ReqvnxRwvhdsNHWs .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ReqvnxRwvhdsNHWs .error-icon{fill:#552222;}#mermaid-svg-ReqvnxRwvhdsNHWs .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ReqvnxRwvhdsNHWs .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ReqvnxRwvhdsNHWs .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ReqvnxRwvhdsNHWs .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ReqvnxRwvhdsNHWs .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ReqvnxRwvhdsNHWs .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ReqvnxRwvhdsNHWs .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ReqvnxRwvhdsNHWs .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ReqvnxRwvhdsNHWs .marker.cross{stroke:#333333;}#mermaid-svg-ReqvnxRwvhdsNHWs svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ReqvnxRwvhdsNHWs p{margin:0;}#mermaid-svg-ReqvnxRwvhdsNHWs .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ReqvnxRwvhdsNHWs .cluster-label text{fill:#333;}#mermaid-svg-ReqvnxRwvhdsNHWs .cluster-label span{color:#333;}#mermaid-svg-ReqvnxRwvhdsNHWs .cluster-label span p{background-color:transparent;}#mermaid-svg-ReqvnxRwvhdsNHWs .label text,#mermaid-svg-ReqvnxRwvhdsNHWs span{fill:#333;color:#333;}#mermaid-svg-ReqvnxRwvhdsNHWs .node rect,#mermaid-svg-ReqvnxRwvhdsNHWs .node circle,#mermaid-svg-ReqvnxRwvhdsNHWs .node ellipse,#mermaid-svg-ReqvnxRwvhdsNHWs .node polygon,#mermaid-svg-ReqvnxRwvhdsNHWs .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ReqvnxRwvhdsNHWs .rough-node .label text,#mermaid-svg-ReqvnxRwvhdsNHWs .node .label text,#mermaid-svg-ReqvnxRwvhdsNHWs .image-shape .label,#mermaid-svg-ReqvnxRwvhdsNHWs .icon-shape .label{text-anchor:middle;}#mermaid-svg-ReqvnxRwvhdsNHWs .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ReqvnxRwvhdsNHWs .rough-node .label,#mermaid-svg-ReqvnxRwvhdsNHWs .node .label,#mermaid-svg-ReqvnxRwvhdsNHWs .image-shape .label,#mermaid-svg-ReqvnxRwvhdsNHWs .icon-shape .label{text-align:center;}#mermaid-svg-ReqvnxRwvhdsNHWs .node.clickable{cursor:pointer;}#mermaid-svg-ReqvnxRwvhdsNHWs .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ReqvnxRwvhdsNHWs .arrowheadPath{fill:#333333;}#mermaid-svg-ReqvnxRwvhdsNHWs .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ReqvnxRwvhdsNHWs .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ReqvnxRwvhdsNHWs .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ReqvnxRwvhdsNHWs .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ReqvnxRwvhdsNHWs .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ReqvnxRwvhdsNHWs .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ReqvnxRwvhdsNHWs .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ReqvnxRwvhdsNHWs .cluster text{fill:#333;}#mermaid-svg-ReqvnxRwvhdsNHWs .cluster span{color:#333;}#mermaid-svg-ReqvnxRwvhdsNHWs div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ReqvnxRwvhdsNHWs .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ReqvnxRwvhdsNHWs rect.text{fill:none;stroke-width:0;}#mermaid-svg-ReqvnxRwvhdsNHWs .icon-shape,#mermaid-svg-ReqvnxRwvhdsNHWs .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ReqvnxRwvhdsNHWs .icon-shape p,#mermaid-svg-ReqvnxRwvhdsNHWs .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ReqvnxRwvhdsNHWs .icon-shape .label rect,#mermaid-svg-ReqvnxRwvhdsNHWs .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ReqvnxRwvhdsNHWs .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ReqvnxRwvhdsNHWs .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ReqvnxRwvhdsNHWs :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Java 堆
新生代
老年代
Eden
Survivor From
Survivor To
常见默认比例会看到新生代中 Eden 和两个 Survivor 约为 8:1:1,但现代 JVM 会受垃圾回收器、自适应策略和参数影响,不要把这个比例当成所有场景下绝对固定。
对象分配和晋升流程
普通对象通常先分配到 Eden 区。Eden 空间不足时触发 Minor GC,把 Eden 和 Survivor 中仍然存活的对象复制到另一个 Survivor 区;对象年龄增长到一定阈值,或者 Survivor 放不下,就可能晋升到老年代。
#mermaid-svg-rIEMmCftMVraV8o6{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rIEMmCftMVraV8o6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rIEMmCftMVraV8o6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rIEMmCftMVraV8o6 .error-icon{fill:#552222;}#mermaid-svg-rIEMmCftMVraV8o6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rIEMmCftMVraV8o6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rIEMmCftMVraV8o6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rIEMmCftMVraV8o6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rIEMmCftMVraV8o6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rIEMmCftMVraV8o6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rIEMmCftMVraV8o6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rIEMmCftMVraV8o6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rIEMmCftMVraV8o6 .marker.cross{stroke:#333333;}#mermaid-svg-rIEMmCftMVraV8o6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rIEMmCftMVraV8o6 p{margin:0;}#mermaid-svg-rIEMmCftMVraV8o6 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rIEMmCftMVraV8o6 .cluster-label text{fill:#333;}#mermaid-svg-rIEMmCftMVraV8o6 .cluster-label span{color:#333;}#mermaid-svg-rIEMmCftMVraV8o6 .cluster-label span p{background-color:transparent;}#mermaid-svg-rIEMmCftMVraV8o6 .label text,#mermaid-svg-rIEMmCftMVraV8o6 span{fill:#333;color:#333;}#mermaid-svg-rIEMmCftMVraV8o6 .node rect,#mermaid-svg-rIEMmCftMVraV8o6 .node circle,#mermaid-svg-rIEMmCftMVraV8o6 .node ellipse,#mermaid-svg-rIEMmCftMVraV8o6 .node polygon,#mermaid-svg-rIEMmCftMVraV8o6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rIEMmCftMVraV8o6 .rough-node .label text,#mermaid-svg-rIEMmCftMVraV8o6 .node .label text,#mermaid-svg-rIEMmCftMVraV8o6 .image-shape .label,#mermaid-svg-rIEMmCftMVraV8o6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-rIEMmCftMVraV8o6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rIEMmCftMVraV8o6 .rough-node .label,#mermaid-svg-rIEMmCftMVraV8o6 .node .label,#mermaid-svg-rIEMmCftMVraV8o6 .image-shape .label,#mermaid-svg-rIEMmCftMVraV8o6 .icon-shape .label{text-align:center;}#mermaid-svg-rIEMmCftMVraV8o6 .node.clickable{cursor:pointer;}#mermaid-svg-rIEMmCftMVraV8o6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rIEMmCftMVraV8o6 .arrowheadPath{fill:#333333;}#mermaid-svg-rIEMmCftMVraV8o6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rIEMmCftMVraV8o6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rIEMmCftMVraV8o6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rIEMmCftMVraV8o6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rIEMmCftMVraV8o6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rIEMmCftMVraV8o6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rIEMmCftMVraV8o6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rIEMmCftMVraV8o6 .cluster text{fill:#333;}#mermaid-svg-rIEMmCftMVraV8o6 .cluster span{color:#333;}#mermaid-svg-rIEMmCftMVraV8o6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rIEMmCftMVraV8o6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rIEMmCftMVraV8o6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-rIEMmCftMVraV8o6 .icon-shape,#mermaid-svg-rIEMmCftMVraV8o6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rIEMmCftMVraV8o6 .icon-shape p,#mermaid-svg-rIEMmCftMVraV8o6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rIEMmCftMVraV8o6 .icon-shape .label rect,#mermaid-svg-rIEMmCftMVraV8o6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rIEMmCftMVraV8o6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rIEMmCftMVraV8o6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rIEMmCftMVraV8o6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 放得下
放不下
否
是
新对象创建
优先进入 Eden
Eden 是否放得下
继续运行
触发 Minor GC
标记 Eden 和 Survivor 存活对象
复制到另一个 Survivor
对象年龄或空间是否达到晋升条件
继续留在新生代
晋升老年代
这里有几个常见晋升条件:
| 条件 | 说明 |
|---|---|
| 对象年龄达到阈值 | 多次 Minor GC 后仍存活 |
| Survivor 空间不足 | 放不下的存活对象提前进入老年代 |
| 大对象直接进入老年代 | 避免在新生代频繁复制大对象 |
| 动态年龄判断 | 某些年龄段对象总大小过大时提前晋升 |
晋升阈值常通过 -XX:MaxTenuringThreshold 控制,最大通常是 15,因为对象年龄在对象头中可用位数有限。
对象一定先进 Eden 吗
不一定。
"对象通常先进 Eden"是理解分代回收的主线,但真实 JVM 会有一些优化和例外。
| 情况 | 说明 |
|---|---|
| TLAB 分配 | 对象可能先分配到线程自己的 TLAB,本质上仍属于 Eden |
| 大对象 | 可能直接进入老年代,避免在新生代来回复制 |
| 长期存活对象 | 多次 Minor GC 后晋升老年代 |
| Survivor 放不下 | 存活对象可能提前进入老年代 |
| 逃逸分析优化 | 对象可能被标量替换,不形成完整堆对象 |
#mermaid-svg-9gJG1zSTDnVeD6fy{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9gJG1zSTDnVeD6fy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9gJG1zSTDnVeD6fy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9gJG1zSTDnVeD6fy .error-icon{fill:#552222;}#mermaid-svg-9gJG1zSTDnVeD6fy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9gJG1zSTDnVeD6fy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9gJG1zSTDnVeD6fy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9gJG1zSTDnVeD6fy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9gJG1zSTDnVeD6fy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9gJG1zSTDnVeD6fy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9gJG1zSTDnVeD6fy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9gJG1zSTDnVeD6fy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9gJG1zSTDnVeD6fy .marker.cross{stroke:#333333;}#mermaid-svg-9gJG1zSTDnVeD6fy svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9gJG1zSTDnVeD6fy p{margin:0;}#mermaid-svg-9gJG1zSTDnVeD6fy .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-9gJG1zSTDnVeD6fy .cluster-label text{fill:#333;}#mermaid-svg-9gJG1zSTDnVeD6fy .cluster-label span{color:#333;}#mermaid-svg-9gJG1zSTDnVeD6fy .cluster-label span p{background-color:transparent;}#mermaid-svg-9gJG1zSTDnVeD6fy .label text,#mermaid-svg-9gJG1zSTDnVeD6fy span{fill:#333;color:#333;}#mermaid-svg-9gJG1zSTDnVeD6fy .node rect,#mermaid-svg-9gJG1zSTDnVeD6fy .node circle,#mermaid-svg-9gJG1zSTDnVeD6fy .node ellipse,#mermaid-svg-9gJG1zSTDnVeD6fy .node polygon,#mermaid-svg-9gJG1zSTDnVeD6fy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9gJG1zSTDnVeD6fy .rough-node .label text,#mermaid-svg-9gJG1zSTDnVeD6fy .node .label text,#mermaid-svg-9gJG1zSTDnVeD6fy .image-shape .label,#mermaid-svg-9gJG1zSTDnVeD6fy .icon-shape .label{text-anchor:middle;}#mermaid-svg-9gJG1zSTDnVeD6fy .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9gJG1zSTDnVeD6fy .rough-node .label,#mermaid-svg-9gJG1zSTDnVeD6fy .node .label,#mermaid-svg-9gJG1zSTDnVeD6fy .image-shape .label,#mermaid-svg-9gJG1zSTDnVeD6fy .icon-shape .label{text-align:center;}#mermaid-svg-9gJG1zSTDnVeD6fy .node.clickable{cursor:pointer;}#mermaid-svg-9gJG1zSTDnVeD6fy .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9gJG1zSTDnVeD6fy .arrowheadPath{fill:#333333;}#mermaid-svg-9gJG1zSTDnVeD6fy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9gJG1zSTDnVeD6fy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9gJG1zSTDnVeD6fy .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9gJG1zSTDnVeD6fy .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9gJG1zSTDnVeD6fy .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9gJG1zSTDnVeD6fy .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9gJG1zSTDnVeD6fy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9gJG1zSTDnVeD6fy .cluster text{fill:#333;}#mermaid-svg-9gJG1zSTDnVeD6fy .cluster span{color:#333;}#mermaid-svg-9gJG1zSTDnVeD6fy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-9gJG1zSTDnVeD6fy .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9gJG1zSTDnVeD6fy rect.text{fill:none;stroke-width:0;}#mermaid-svg-9gJG1zSTDnVeD6fy .icon-shape,#mermaid-svg-9gJG1zSTDnVeD6fy .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9gJG1zSTDnVeD6fy .icon-shape p,#mermaid-svg-9gJG1zSTDnVeD6fy .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9gJG1zSTDnVeD6fy .icon-shape .label rect,#mermaid-svg-9gJG1zSTDnVeD6fy .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9gJG1zSTDnVeD6fy .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9gJG1zSTDnVeD6fy .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9gJG1zSTDnVeD6fy :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 能
不能
是
否
可用
不可用
对象创建
JIT 是否能优化掉
可能标量替换
是否大对象
可能直接进入老年代
TLAB 是否可用
进入线程 TLAB
进入 Eden 公共区域
所以面试时更稳的表达是:绝大多数普通对象会优先在新生代 Eden 分配,但大对象、TLAB、逃逸分析、空间担保等机制会带来例外。
Minor GC、Major GC、Full GC、Mixed GC
这些名词也很容易混:
| 名称 | 回收范围 | 常见特点 |
|---|---|---|
| Minor GC | 新生代 | 触发频繁,停顿通常较短 |
| Major GC | 老年代 | 不同语境含义不完全一致,需要结合收集器 |
| Full GC | 整个堆和相关区域 | 停顿通常较长,应重点关注 |
| Mixed GC | 新生代加部分老年代 Region | G1 中的混合回收 |
Stop The World 简称 STW,意思是垃圾回收过程中应用线程暂停,等待 GC 线程完成某些关键阶段。
"GC 线程" "应用线程" "GC 线程" "应用线程" #mermaid-svg-S51CCvQBlTpOU1Yb{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-S51CCvQBlTpOU1Yb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-S51CCvQBlTpOU1Yb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-S51CCvQBlTpOU1Yb .error-icon{fill:#552222;}#mermaid-svg-S51CCvQBlTpOU1Yb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-S51CCvQBlTpOU1Yb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-S51CCvQBlTpOU1Yb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-S51CCvQBlTpOU1Yb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-S51CCvQBlTpOU1Yb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-S51CCvQBlTpOU1Yb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-S51CCvQBlTpOU1Yb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-S51CCvQBlTpOU1Yb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-S51CCvQBlTpOU1Yb .marker.cross{stroke:#333333;}#mermaid-svg-S51CCvQBlTpOU1Yb svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-S51CCvQBlTpOU1Yb p{margin:0;}#mermaid-svg-S51CCvQBlTpOU1Yb .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-S51CCvQBlTpOU1Yb text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-S51CCvQBlTpOU1Yb .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-S51CCvQBlTpOU1Yb .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-S51CCvQBlTpOU1Yb .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-S51CCvQBlTpOU1Yb .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-S51CCvQBlTpOU1Yb #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-S51CCvQBlTpOU1Yb .sequenceNumber{fill:white;}#mermaid-svg-S51CCvQBlTpOU1Yb #sequencenumber{fill:#333;}#mermaid-svg-S51CCvQBlTpOU1Yb #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-S51CCvQBlTpOU1Yb .messageText{fill:#333;stroke:none;}#mermaid-svg-S51CCvQBlTpOU1Yb .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-S51CCvQBlTpOU1Yb .labelText,#mermaid-svg-S51CCvQBlTpOU1Yb .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-S51CCvQBlTpOU1Yb .loopText,#mermaid-svg-S51CCvQBlTpOU1Yb .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-S51CCvQBlTpOU1Yb .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-S51CCvQBlTpOU1Yb .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-S51CCvQBlTpOU1Yb .noteText,#mermaid-svg-S51CCvQBlTpOU1Yb .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-S51CCvQBlTpOU1Yb .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-S51CCvQBlTpOU1Yb .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-S51CCvQBlTpOU1Yb .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-S51CCvQBlTpOU1Yb .actorPopupMenu{position:absolute;}#mermaid-svg-S51CCvQBlTpOU1Yb .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-S51CCvQBlTpOU1Yb .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-S51CCvQBlTpOU1Yb .actor-man circle,#mermaid-svg-S51CCvQBlTpOU1Yb line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-S51CCvQBlTpOU1Yb :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} "正常执行业务""触发 STW""暂停""标记或复制对象""恢复应用线程""继续执行业务"
GC 优化很多时候就是在吞吐量、停顿时间和内存占用之间做取舍。
分代回收为什么高效
分代回收的核心是"用不同算法处理不同生命周期的对象"。
#mermaid-svg-MHxtn7IvcwVcDuUS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MHxtn7IvcwVcDuUS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MHxtn7IvcwVcDuUS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MHxtn7IvcwVcDuUS .error-icon{fill:#552222;}#mermaid-svg-MHxtn7IvcwVcDuUS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MHxtn7IvcwVcDuUS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MHxtn7IvcwVcDuUS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MHxtn7IvcwVcDuUS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MHxtn7IvcwVcDuUS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MHxtn7IvcwVcDuUS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MHxtn7IvcwVcDuUS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MHxtn7IvcwVcDuUS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MHxtn7IvcwVcDuUS .marker.cross{stroke:#333333;}#mermaid-svg-MHxtn7IvcwVcDuUS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MHxtn7IvcwVcDuUS p{margin:0;}#mermaid-svg-MHxtn7IvcwVcDuUS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MHxtn7IvcwVcDuUS .cluster-label text{fill:#333;}#mermaid-svg-MHxtn7IvcwVcDuUS .cluster-label span{color:#333;}#mermaid-svg-MHxtn7IvcwVcDuUS .cluster-label span p{background-color:transparent;}#mermaid-svg-MHxtn7IvcwVcDuUS .label text,#mermaid-svg-MHxtn7IvcwVcDuUS span{fill:#333;color:#333;}#mermaid-svg-MHxtn7IvcwVcDuUS .node rect,#mermaid-svg-MHxtn7IvcwVcDuUS .node circle,#mermaid-svg-MHxtn7IvcwVcDuUS .node ellipse,#mermaid-svg-MHxtn7IvcwVcDuUS .node polygon,#mermaid-svg-MHxtn7IvcwVcDuUS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MHxtn7IvcwVcDuUS .rough-node .label text,#mermaid-svg-MHxtn7IvcwVcDuUS .node .label text,#mermaid-svg-MHxtn7IvcwVcDuUS .image-shape .label,#mermaid-svg-MHxtn7IvcwVcDuUS .icon-shape .label{text-anchor:middle;}#mermaid-svg-MHxtn7IvcwVcDuUS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MHxtn7IvcwVcDuUS .rough-node .label,#mermaid-svg-MHxtn7IvcwVcDuUS .node .label,#mermaid-svg-MHxtn7IvcwVcDuUS .image-shape .label,#mermaid-svg-MHxtn7IvcwVcDuUS .icon-shape .label{text-align:center;}#mermaid-svg-MHxtn7IvcwVcDuUS .node.clickable{cursor:pointer;}#mermaid-svg-MHxtn7IvcwVcDuUS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MHxtn7IvcwVcDuUS .arrowheadPath{fill:#333333;}#mermaid-svg-MHxtn7IvcwVcDuUS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MHxtn7IvcwVcDuUS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MHxtn7IvcwVcDuUS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MHxtn7IvcwVcDuUS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MHxtn7IvcwVcDuUS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MHxtn7IvcwVcDuUS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MHxtn7IvcwVcDuUS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MHxtn7IvcwVcDuUS .cluster text{fill:#333;}#mermaid-svg-MHxtn7IvcwVcDuUS .cluster span{color:#333;}#mermaid-svg-MHxtn7IvcwVcDuUS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MHxtn7IvcwVcDuUS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MHxtn7IvcwVcDuUS rect.text{fill:none;stroke-width:0;}#mermaid-svg-MHxtn7IvcwVcDuUS .icon-shape,#mermaid-svg-MHxtn7IvcwVcDuUS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MHxtn7IvcwVcDuUS .icon-shape p,#mermaid-svg-MHxtn7IvcwVcDuUS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MHxtn7IvcwVcDuUS .icon-shape .label rect,#mermaid-svg-MHxtn7IvcwVcDuUS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MHxtn7IvcwVcDuUS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MHxtn7IvcwVcDuUS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MHxtn7IvcwVcDuUS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 新生代
对象存活率低
复制算法更合适
老年代
对象存活率高
标记清除或标记整理更合适
如果新生代每次 GC 后只有少量对象存活,复制算法只需要复制少量对象,剩下空间整体清空,速度很快。
如果老年代大多数对象都存活,复制算法就会变成大量搬运,成本很高,因此更适合标记整理或标记清除类算法。
面试回答模板
可以这样回答:
JVM 常见垃圾回收算法有标记清除、标记整理和复制算法。标记清除先标记垃圾对象再清除,速度较快但会产生内存碎片;标记整理会把存活对象向一端移动,再清理边界外空间,解决碎片问题但移动对象成本更高;复制算法把存活对象复制到另一块空间,再清空原空间,适合存活对象少的新生代。JVM 做分代回收是因为大多数对象生命周期很短,少数对象存活较久,所以新对象通常先进 Eden,Minor GC 后存活对象进入 Survivor,多次存活或 Survivor 放不下时晋升老年代。Minor GC 主要回收新生代,Full GC 通常回收范围更大、停顿更长,线上需要重点关注。
小结
垃圾回收算法和分代回收可以用一句话串起来:
新生代垃圾多、存活少,适合复制;老年代存活多、搬动贵,适合标记清除或标记整理。
理解这个取舍,比单纯背算法定义更重要。