JVM 垃圾回收算法与分代回收机制

垃圾回收不只是"把没用的对象清掉"。真正要回答清楚 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 通常回收范围更大、停顿更长,线上需要重点关注。

小结

垃圾回收算法和分代回收可以用一句话串起来:

新生代垃圾多、存活少,适合复制;老年代存活多、搬动贵,适合标记清除或标记整理。

理解这个取舍,比单纯背算法定义更重要。

相关推荐
智者知已应修善业1 小时前
【51单片机初始化D5-D8亮,每按键按下D1到D4全亮,再按下恢复,如此循环】2024-3-26
c++·经验分享·笔记·算法·51单片机
摇滚侠1 小时前
SpringMVC 入门到实战 简介和入门案例 01-13
java·后端·spring·intellij-idea
未若君雅裁1 小时前
JVM 垃圾回收器全景与G1深度解析
java·开发语言·jvm
霸道流氓气质1 小时前
Java 大数据量异步处理方案:线程池 vs 消息队列
java·开发语言
devilnumber1 小时前
想真正吃透 + 灵活运用 Java 代理模式
java·开发语言·代理模式
蝎子莱莱爱打怪1 小时前
自用推荐|XTerminal:我心中 SSH 客户端的终极形态
java·后端·程序员
AIGS0011 小时前
向量空间JBoltAI:重塑工业智能的四大支柱
java·人工智能·ai大模型应用
刘科领1 小时前
修改jdk 第一步: 仓库以及构建(jdk17)
java·开发语言
C+-C资深大佬2 小时前
C++ 中的 constexpr与 const区
java·开发语言·c++