Xiaomi Mimo UltraSpeed初体验

上次参与了Xiaomi 100T Token的活动,最后得了820亿Token,花了20亿。不得不说白嫖的确实香。
最近Xiaomi又给我发邮件, v2.5-UltraSpeed内测延期,我也是赶快申请,刚刚通过审核。

用的网页版,先问了Go中GC流程,用了text展示流程
3fa0b0040ba0ebdcdebfd20ef0a51429

点击查看代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Go GC 三色标记流程图解</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link
        href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;600;700&family=Noto+Sans+SC:wght@300;400;500;700;900&display=swap"
        rel="stylesheet">
    <style>
        :root {
            --bg: #0a0e17;
            --surface: #111827;
            --surface2: #1a2235;
            --border: #1e2d45;
            --accent: #22d3ee;
            --accent2: #f59e0b;
            --accent3: #10b981;
            --red: #ef4444;
            --white-obj: #e2e8f0;
            --grey-obj: #94a3b8;
            --black-obj: #1e293b;
            --text: #e2e8f0;
            --text-muted: #64748b;
            --stw-red: rgba(239, 68, 68, 0.12);
            --stw-border: rgba(239, 68, 68, 0.4);
            --mark-blue: rgba(34, 211, 238, 0.08);
            --mark-border: rgba(34, 211, 238, 0.3);
            --sweep-green: rgba(16, 185, 129, 0.08);
            --sweep-border: rgba(16, 185, 129, 0.3);
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            background: var(--bg);
            color: var(--text);
            font-family: 'Noto Sans SC', sans-serif;
            line-height: 1.7;
            overflow-x: hidden;
        }

        body::before {
            content: '';
            position: fixed;
            inset: 0;
            background:
                radial-gradient(ellipse at 15% 20%, rgba(34, 211, 238, 0.04) 0%, transparent 50%),
                radial-gradient(ellipse at 85% 80%, rgba(245, 158, 11, 0.03) 0%, transparent 50%),
                radial-gradient(ellipse at 50% 50%, rgba(16, 185, 129, 0.02) 0%, transparent 70%);
            pointer-events: none;
            z-index: 0;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 0 24px;
            position: relative;
            z-index: 1;
        }

        /* Header */
        header {
            padding: 80px 0 40px;
            text-align: center;
        }

        header .badge {
            display: inline-block;
            font-family: 'JetBrains Mono', monospace;
            font-size: 12px;
            letter-spacing: 3px;
            text-transform: uppercase;
            color: var(--accent);
            border: 1px solid rgba(34, 211, 238, 0.3);
            padding: 6px 20px;
            border-radius: 100px;
            margin-bottom: 28px;
            background: rgba(34, 211, 238, 0.05);
        }

        h1 {
            font-size: clamp(2rem, 5vw, 3.5rem);
            font-weight: 900;
            letter-spacing: -1px;
            margin-bottom: 16px;
            background: linear-gradient(135deg, #e2e8f0, #94a3b8);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }

        header p {
            color: var(--text-muted);
            font-size: 1.05rem;
            max-width: 640px;
            margin: 0 auto;
        }

        /* Color Legend */
        .legend-bar {
            display: flex;
            justify-content: center;
            gap: 32px;
            margin: 48px 0 60px;
            flex-wrap: wrap;
        }

        .legend-item {
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 0.95rem;
            color: var(--text-muted);
        }

        .legend-dot {
            width: 28px;
            height: 28px;
            border-radius: 50%;
            border: 3px solid;
            flex-shrink: 0;
        }

        .legend-dot.white {
            background: #e2e8f0;
            border-color: #94a3b8;
        }

        .legend-dot.grey {
            background: #94a3b8;
            border-color: #64748b;
        }

        .legend-dot.black {
            background: #1e293b;
            border-color: #22d3ee;
        }

        /* Timeline */
        .timeline {
            position: relative;
            margin-bottom: 80px;
        }

        .timeline-line {
            position: absolute;
            left: 50%;
            top: 0;
            bottom: 0;
            width: 3px;
            background: linear-gradient(to bottom, var(--border), var(--accent), var(--border));
            transform: translateX(-50%);
            border-radius: 2px;
        }

        .phase {
            position: relative;
            margin-bottom: 80px;
            opacity: 0;
            transform: translateY(30px);
            animation: fadeInUp 0.6s ease forwards;
        }

        .phase:nth-child(2) {
            animation-delay: 0.1s;
        }

        .phase:nth-child(3) {
            animation-delay: 0.2s;
        }

        .phase:nth-child(4) {
            animation-delay: 0.3s;
        }

        .phase:nth-child(5) {
            animation-delay: 0.4s;
        }

        .phase:nth-child(6) {
            animation-delay: 0.5s;
        }

        @keyframes fadeInUp {
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .phase-marker {
            position: absolute;
            left: 50%;
            top: 24px;
            transform: translateX(-50%);
            z-index: 3;
        }

        .marker-dot {
            width: 48px;
            height: 48px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-family: 'JetBrains Mono', monospace;
            font-weight: 700;
            font-size: 16px;
            border: 3px solid;
            background: var(--bg);
        }

        .marker-dot.stw {
            border-color: var(--red);
            color: var(--red);
            box-shadow: 0 0 20px rgba(239, 68, 68, 0.3);
        }

        .marker-dot.concurrent {
            border-color: var(--accent);
            color: var(--accent);
            box-shadow: 0 0 20px rgba(34, 211, 238, 0.2);
        }

        .marker-dot.sweep {
            border-color: var(--accent3);
            color: var(--accent3);
            box-shadow: 0 0 20px rgba(16, 185, 129, 0.2);
        }

        .phase-content {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 60px;
            align-items: start;
        }

        .phase.left .text-panel {
            grid-column: 1;
            text-align: right;
            padding-right: 20px;
        }

        .phase.left .viz-panel {
            grid-column: 2;
            padding-left: 20px;
        }

        .phase.right .text-panel {
            grid-column: 2;
            text-align: left;
            padding-left: 20px;
        }

        .phase.right .viz-panel {
            grid-column: 1;
            text-align: right;
            padding-right: 20px;
        }

        .phase-tag {
            display: inline-block;
            font-family: 'JetBrains Mono', monospace;
            font-size: 11px;
            letter-spacing: 2px;
            text-transform: uppercase;
            padding: 4px 14px;
            border-radius: 4px;
            margin-bottom: 12px;
        }

        .phase-tag.stw {
            background: var(--stw-red);
            color: var(--red);
            border: 1px solid var(--stw-border);
        }

        .phase-tag.concurrent {
            background: var(--mark-blue);
            color: var(--accent);
            border: 1px solid var(--mark-border);
        }

        .phase-tag.sweep-tag {
            background: var(--sweep-green);
            color: var(--accent3);
            border: 1px solid var(--sweep-border);
        }

        .phase-title {
            font-size: 1.6rem;
            font-weight: 700;
            margin-bottom: 12px;
            letter-spacing: -0.5px;
        }

        .phase-desc {
            color: var(--text-muted);
            font-size: 0.95rem;
            line-height: 1.8;
        }

        .phase-desc strong {
            color: var(--text);
        }

        /* Visualization panels */
        .viz-card {
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: 16px;
            padding: 28px;
            position: relative;
            overflow: hidden;
        }

        .viz-card::before {
            content: '';
            position: absolute;
            inset: 0;
            background: linear-gradient(135deg, rgba(34, 211, 238, 0.03), transparent);
            pointer-events: none;
        }

        .viz-card.stw-card {
            border-color: var(--stw-border);
        }

        .viz-card.concurrent-card {
            border-color: var(--mark-border);
        }

        .viz-card.sweep-card {
            border-color: var(--sweep-border);
        }

        /* Object Graph */
        .obj-graph {
            display: flex;
            flex-direction: column;
            gap: 24px;
            position: relative;
        }

        .graph-row {
            display: flex;
            align-items: center;
            gap: 12px;
            justify-content: center;
            flex-wrap: wrap;
        }

        .obj-node {
            width: 56px;
            height: 56px;
            border-radius: 14px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-family: 'JetBrains Mono', monospace;
            font-weight: 700;
            font-size: 15px;
            position: relative;
            transition: all 0.4s ease;
            border: 3px solid;
            flex-shrink: 0;
        }

        .obj-node.white-node {
            background: #334155;
            border-color: #475569;
            color: #94a3b8;
        }

        .obj-node.grey-node {
            background: #475569;
            border-color: var(--accent2);
            color: #fbbf24;
            box-shadow: 0 0 16px rgba(245, 158, 11, 0.25);
            animation: pulseGrey 2s ease-in-out infinite;
        }

        @keyframes pulseGrey {

            0%,
            100% {
                box-shadow: 0 0 16px rgba(245, 158, 11, 0.25);
            }

            50% {
                box-shadow: 0 0 24px rgba(245, 158, 11, 0.4);
            }
        }

        .obj-node.black-node {
            background: var(--bg);
            border-color: var(--accent);
            color: var(--accent);
            box-shadow: 0 0 16px rgba(34, 211, 238, 0.2);
        }

        .obj-node.root-node {
            width: 64px;
            height: 64px;
            border-radius: 50%;
            background: linear-gradient(135deg, #1e1b4b, #312e81);
            border-color: #818cf8;
            color: #a5b4fc;
            font-size: 13px;
        }

        .obj-node.dead-node {
            background: rgba(239, 68, 68, 0.1);
            border-color: rgba(239, 68, 68, 0.4);
            color: var(--red);
            opacity: 0.5;
            text-decoration: line-through;
        }

        .arrow {
            font-family: 'JetBrains Mono', monospace;
            color: var(--text-muted);
            font-size: 18px;
            line-height: 1;
        }

        .arrow.highlight {
            color: var(--accent2);
        }

        .label-sm {
            font-family: 'JetBrains Mono', monospace;
            font-size: 10px;
            color: var(--text-muted);
            text-align: center;
            margin-top: 6px;
        }

        /* Timeline bar */
        .timeline-bar {
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: 12px;
            padding: 24px;
            margin-bottom: 60px;
        }

        .bar-track {
            display: flex;
            height: 52px;
            border-radius: 8px;
            overflow: hidden;
            position: relative;
        }

        .bar-seg {
            display: flex;
            align-items: center;
            justify-content: center;
            font-family: 'JetBrains Mono', monospace;
            font-size: 11px;
            font-weight: 600;
            letter-spacing: 1px;
            text-transform: uppercase;
            position: relative;
            transition: all 0.3s ease;
        }

        .bar-seg:hover {
            filter: brightness(1.3);
        }

        .bar-seg.stw-seg {
            background: rgba(239, 68, 68, 0.2);
            color: var(--red);
            border: 1px solid rgba(239, 68, 68, 0.3);
            flex: 0 0 40px;
        }

        .bar-seg.mark-seg {
            background: rgba(34, 211, 238, 0.12);
            color: var(--accent);
            border: 1px solid rgba(34, 211, 238, 0.2);
            flex: 5;
        }

        .bar-seg.sweep-seg {
            background: rgba(16, 185, 129, 0.1);
            color: var(--accent3);
            border: 1px solid rgba(16, 185, 129, 0.2);
            flex: 3;
        }

        .bar-labels {
            display: flex;
            margin-top: 8px;
            font-family: 'JetBrains Mono', monospace;
            font-size: 10px;
            color: var(--text-muted);
        }

        .bar-labels span:first-child {
            flex: 0 0 40px;
            text-align: center;
        }

        .bar-labels span:nth-child(2) {
            flex: 5;
            text-align: center;
        }

        .bar-labels span:nth-child(3) {
            flex: 0 0 40px;
            text-align: center;
        }

        .bar-labels span:nth-child(4) {
            flex: 3;
            text-align: center;
        }

        /* Write barrier animation */
        .write-demo {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-top: 16px;
            padding: 12px 16px;
            background: rgba(245, 158, 11, 0.06);
            border: 1px solid rgba(245, 158, 11, 0.2);
            border-radius: 8px;
            font-family: 'JetBrains Mono', monospace;
            font-size: 12px;
            color: var(--accent2);
            line-height: 1.6;
        }

        /* Code block */
        .code-block {
            background: var(--bg);
            border: 1px solid var(--border);
            border-radius: 10px;
            padding: 20px;
            margin-top: 16px;
            font-family: 'JetBrains Mono', monospace;
            font-size: 12.5px;
            line-height: 1.8;
            overflow-x: auto;
            color: #94a3b8;
        }

        .code-block .kw {
            color: #c084fc;
        }

        .code-block .fn {
            color: #22d3ee;
        }

        .code-block .str {
            color: #34d399;
        }

        .code-block .cm {
            color: #475569;
        }

        .code-block .op {
            color: #f59e0b;
        }

        /* Step indicator */
        .step-pills {
            display: flex;
            gap: 8px;
            margin-top: 12px;
            flex-wrap: wrap;
        }

        .pill {
            font-family: 'JetBrains Mono', monospace;
            font-size: 11px;
            padding: 4px 12px;
            border-radius: 100px;
            background: var(--surface2);
            color: var(--text-muted);
            border: 1px solid var(--border);
        }

        .pill.active {
            background: rgba(34, 211, 238, 0.1);
            border-color: rgba(34, 211, 238, 0.3);
            color: var(--accent);
        }

        /* Summary Section */
        .summary {
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: 20px;
            padding: 48px;
            margin: 40px 0 100px;
            position: relative;
            overflow: hidden;
        }

        .summary::before {
            content: '';
            position: absolute;
            inset: 0;
            background: linear-gradient(135deg, rgba(34, 211, 238, 0.03), transparent 50%, rgba(245, 158, 11, 0.02));
            pointer-events: none;
        }

        .summary h2 {
            font-size: 1.8rem;
            font-weight: 700;
            margin-bottom: 28px;
        }

        .summary-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
        }

        .summary-card {
            background: var(--bg);
            border: 1px solid var(--border);
            border-radius: 12px;
            padding: 20px;
            text-align: center;
        }

        .summary-card .num {
            font-family: 'JetBrains Mono', monospace;
            font-size: 2rem;
            font-weight: 700;
            margin-bottom: 6px;
        }

        .summary-card .num.red {
            color: var(--red);
        }

        .summary-card .num.cyan {
            color: var(--accent);
        }

        .summary-card .num.green {
            color: var(--accent3);
        }

        .summary-card .num.yellow {
            color: var(--accent2);
        }

        .summary-card .desc {
            font-size: 0.85rem;
            color: var(--text-muted);
        }

        /* Responsive */
        @media (max-width: 768px) {
            .phase-content {
                grid-template-columns: 1fr;
                gap: 20px;
            }

            .phase.left .text-panel,
            .phase.right .text-panel,
            .phase.left .viz-panel,
            .phase.right .viz-panel {
                grid-column: 1;
                text-align: left;
                padding: 0;
            }

            .timeline-line {
                display: none;
            }

            .phase-marker {
                display: none;
            }

            .obj-node {
                width: 44px;
                height: 44px;
                font-size: 12px;
            }

            .obj-node.root-node {
                width: 50px;
                height: 50px;
            }

            header {
                padding: 40px 0 20px;
            }
        }
    </style>
</head>

<body>

    <header>
        <div class="container">
            <div class="badge">Go Runtime &mdash; Garbage Collector</div>
            <h1>三色标记 GC 全流程图解</h1>
            <p>从标记准备到并发清扫,完整理解 Go 垃圾回收器的工作原理与 STW 暂停的必要性</p>
        </div>
    </header>

    <div class="container">

        <!-- Color Legend -->
        <div class="legend-bar">
            <div class="legend-item">
                <div class="legend-dot white"></div>
                <span>白色 = 未扫描 / 待回收</span>
            </div>
            <div class="legend-item">
                <div class="legend-dot grey"></div>
                <span>灰色 = 已发现 / 子节点待扫描</span>
            </div>
            <div class="legend-item">
                <div class="legend-dot black"></div>
                <span>黑色 = 完全扫描 / 确认存活</span>
            </div>
        </div>

        <!-- Overview Timeline Bar -->
        <div class="timeline-bar">
            <div class="bar-track">
                <div class="bar-seg stw-seg">STW</div>
                <div class="bar-seg mark-seg">并发标记 Concurrent Mark</div>
                <div class="bar-seg stw-seg">STW</div>
                <div class="bar-seg sweep-seg">并发清扫 Concurrent Sweep</div>
            </div>
            <div class="bar-labels">
                <span>标记准备</span>
                <span>GC Worker 遍历对象图(应用正常运行)</span>
                <span>标记终止</span>
                <span>回收白色对象</span>
            </div>
        </div>

        <!-- ===== Phase 0: Initial State ===== -->
        <div class="timeline">
            <div class="timeline-line"></div>

            <!-- Phase: Initial State -->
            <div class="phase left" style="animation-delay:0s">
                <div class="phase-marker">
                    <div class="marker-dot concurrent" style="border-color:#475569;color:#475569">0</div>
                </div>
                <div class="text-panel">
                    <div class="phase-tag concurrent"
                        style="background:rgba(71,85,105,0.15);border-color:rgba(71,85,105,0.4);color:#94a3b8">初始状态
                    </div>
                    <div class="phase-title">内存中的一堆对象</div>
                    <div class="phase-desc">
                        堆上有 A~H 共 8 个对象,它们之间有引用关系。<br>
                        其中 <strong style="color:#ef4444">G 和 H 没有被任何人引用</strong>——它们是垃圾,但程序还不知道。<br><br>
                        GC 的任务:找出所有从根可达的对象,剩下的就是垃圾。
                    </div>
                </div>
                <div class="viz-panel">
                    <div class="viz-card">
                        <div class="obj-graph">
                            <div class="graph-row">
                                <div>
                                    <div class="obj-node root-node">栈</div>
                                    <div class="label-sm">goroutine 栈</div>
                                </div>
                                <span class="arrow">&rarr;</span>
                                <div>
                                    <div class="obj-node white-node">A</div>
                                    <div class="label-sm">根对象</div>
                                </div>
                                <span class="arrow">&rarr;</span>
                                <div>
                                    <div class="obj-node white-node">C</div>
                                    <div class="label-sm"></div>
                                </div>
                                <span class="arrow">&rarr;</span>
                                <div>
                                    <div class="obj-node white-node">E</div>
                                    <div class="label-sm"></div>
                                </div>
                            </div>
                            <div class="graph-row" style="padding-left:120px">
                                <span class="arrow">&swarr;</span>
                                <div>
                                    <div class="obj-node white-node">B</div>
                                </div>
                                <span class="arrow">&rarr;</span>
                                <div>
                                    <div class="obj-node white-node">D</div>
                                </div>
                                <span class="arrow">&rarr;</span>
                                <div>
                                    <div class="obj-node white-node">F</div>
                                </div>
                            </div>
                            <div class="graph-row" style="padding-left:200px;margin-top:8px">
                                <div>
                                    <div class="obj-node dead-node">G</div>
                                    <div class="label-sm" style="color:var(--red)">无引用</div>
                                </div>
                                <span class="arrow" style="margin:0 12px">&nbsp;</span>
                                <div>
                                    <div class="obj-node dead-node">H</div>
                                    <div class="label-sm" style="color:var(--red)">无引用</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Phase 1: STW Mark Setup -->
            <div class="phase right">
                <div class="phase-marker">
                    <div class="marker-dot stw">1</div>
                </div>
                <div class="text-panel">
                    <div class="phase-tag stw">STW &mdash; 约 0.1ms</div>
                    <div class="phase-title">标记准备 Mark Setup</div>
                    <div class="phase-desc">
                        <strong>第一次短暂暂停应用。</strong><br><br>
                        做两件事:<br>
                        <strong style="color:#ef4444">① 开启写屏障</strong> (Write Barrier)<br>
                        在每个指针写入操作前插入监控代码。这样并发标记期间如果应用修改了引用关系,GC 不会遗漏。<br><br>
                        <strong style="color:#ef4444">② 扫描所有 goroutine 栈</strong><br>
                        找到栈上的指针,作为 GC 遍历的"入口",全部标为灰色放入工作队列。
                    </div>
                    <div class="code-block">
                        <span class="cm">// 写屏障:每次写指针前自动执行</span><br>
                        <span class="kw">func</span> <span class="fn">writeBarrier</span>(slot, ptr *Object) {<br>
                        &nbsp;&nbsp;<span class="fn">shade</span>(ptr) &nbsp;&nbsp;&nbsp;<span class="cm">//
                            把目标标灰,保证不丢</span><br>
                        &nbsp;&nbsp;*slot = ptr &nbsp;&nbsp;&nbsp;<span class="cm">// 正常写入</span><br>
                        }
                    </div>
                </div>
                <div class="viz-panel">
                    <div class="viz-card stw-card">
                        <div style="text-align:center;margin-bottom:16px">
                            <span
                                style="font-family:'JetBrains Mono';font-size:11px;color:var(--red);letter-spacing:2px">APPLICATION
                                PAUSED</span>
                        </div>
                        <div class="obj-graph">
                            <div class="graph-row">
                                <div>
                                    <div class="obj-node root-node" style="opacity:0.5">栈</div>
                                    <div class="label-sm">暂停中...</div>
                                </div>
                                <span class="arrow">&rarr;</span>
                                <div>
                                    <div class="obj-node grey-node">A</div>
                                    <div class="label-sm">标灰 &#x2192; 入队</div>
                                </div>
                            </div>
                            <div class="graph-row" style="padding-left:60px">
                                <span class="arrow">&swarr;</span>
                                <div>
                                    <div class="obj-node grey-node">B</div>
                                    <div class="label-sm">标灰 &#x2192; 入队</div>
                                </div>
                            </div>
                            <div style="text-align:center;margin-top:8px">
                                <div class="graph-row" style="justify-content:center">
                                    <div>
                                        <div class="obj-node white-node">C</div>
                                    </div>
                                    <span class="arrow" style="margin:0 8px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node white-node">D</div>
                                    </div>
                                    <span class="arrow" style="margin:0 8px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node white-node">E</div>
                                    </div>
                                    <span class="arrow" style="margin:0 8px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node white-node">F</div>
                                    </div>
                                </div>
                                <div class="label-sm">仍为白色(未处理)</div>
                            </div>
                            <div class="graph-row" style="justify-content:center;margin-top:8px">
                                <div>
                                    <div class="obj-node dead-node">G</div>
                                </div>
                                <span class="arrow" style="margin:0 12px">&nbsp;</span>
                                <div>
                                    <div class="obj-node dead-node">H</div>
                                </div>
                            </div>
                        </div>
                        <div class="step-pills" style="justify-content:center;margin-top:16px">
                            <div class="pill active">写屏障 ON</div>
                            <div class="pill active">栈根扫描</div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Phase 2: Concurrent Marking -->
            <div class="phase left">
                <div class="phase-marker">
                    <div class="marker-dot concurrent">2</div>
                </div>
                <div class="text-panel">
                    <div class="phase-tag concurrent">并发 &mdash; 时间最长的阶段</div>
                    <div class="phase-title">并发标记 Concurrent Mark</div>
                    <div class="phase-desc">
                        <strong>应用恢复运行!</strong> GC Worker goroutine 与应用并发执行。<br><br>
                        核心逻辑:<strong style="color:var(--accent2)">不断从灰色队列取对象,扫描其子指针</strong><br><br>
                        <strong>每一步:</strong><br>
                        1. 取出一个灰色对象<br>
                        2. 遍历它的所有指针字段<br>
                        3. 子对象若为白色 → 标灰并入队<br>
                        4. 自己标黑(扫描完毕)<br>
                        5. 重复直到队列为空<br><br>
                        此时如果应用执行了 <code style="color:var(--accent2)">objA.ptr = objX</code>,<br>
                        写屏障会把 X 标灰,防止误回收。
                    </div>
                    <div class="write-demo">
                        <span style="font-size:16px">&#9889;</span>
                        <span>应用写入 <span style="color:#f0abfc">A.ptr = X</span> &rarr; 写屏障拦截 &rarr; <span
                                style="color:var(--accent2)">X 标灰入队</span></span>
                    </div>
                </div>
                <div class="viz-panel">
                    <div class="viz-card concurrent-card">
                        <div style="text-align:center;margin-bottom:16px">
                            <span
                                style="font-family:'JetBrains Mono';font-size:11px;color:var(--accent);letter-spacing:2px">APPLICATION
                                RUNNING + GC WORKERS</span>
                        </div>
                        <div class="obj-graph" id="markSteps">
                            <!-- Step by step marking -->
                            <div>
                                <div
                                    style="font-family:'JetBrains Mono';font-size:11px;color:var(--text-muted);margin-bottom:8px">
                                    Round 1: A → 查子指针 → 发现 C</div>
                                <div class="graph-row">
                                    <div>
                                        <div class="obj-node black-node">A</div>
                                        <div class="label-sm">黑</div>
                                    </div>
                                    <span class="arrow highlight">&rarr;</span>
                                    <div>
                                        <div class="obj-node grey-node">C</div>
                                        <div class="label-sm">新灰</div>
                                    </div>
                                    <span class="arrow" style="margin:0 6px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node grey-node">B</div>
                                        <div class="label-sm">仍在队列</div>
                                    </div>
                                </div>
                            </div>
                            <hr style="border:none;border-top:1px solid var(--border);margin:16px 0">
                            <div>
                                <div
                                    style="font-family:'JetBrains Mono';font-size:11px;color:var(--text-muted);margin-bottom:8px">
                                    Round 2: B → 查子指针 → 发现 D</div>
                                <div class="graph-row">
                                    <div>
                                        <div class="obj-node black-node">A</div>
                                        <div class="label-sm">黑</div>
                                    </div>
                                    <span class="arrow" style="margin:0 4px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node black-node">B</div>
                                        <div class="label-sm">新黑</div>
                                    </div>
                                    <span class="arrow highlight">&rarr;</span>
                                    <div>
                                        <div class="obj-node grey-node">D</div>
                                        <div class="label-sm">新灰</div>
                                    </div>
                                    <span class="arrow" style="margin:0 4px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node grey-node">C</div>
                                        <div class="label-sm">仍在队列</div>
                                    </div>
                                </div>
                            </div>
                            <hr style="border:none;border-top:1px solid var(--border);margin:16px 0">
                            <div>
                                <div
                                    style="font-family:'JetBrains Mono';font-size:11px;color:var(--text-muted);margin-bottom:8px">
                                    Round 3: C → 发现 E &nbsp;|&nbsp; Round 4: D → 发现 F</div>
                                <div class="graph-row">
                                    <div>
                                        <div class="obj-node black-node">A</div>
                                    </div>
                                    <span class="arrow" style="margin:0 4px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node black-node">B</div>
                                    </div>
                                    <span class="arrow" style="margin:0 4px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node black-node">C</div>
                                    </div>
                                    <span class="arrow highlight">&rarr;</span>
                                    <div>
                                        <div class="obj-node grey-node">E</div>
                                    </div>
                                    <span class="arrow" style="margin:0 4px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node black-node">D</div>
                                    </div>
                                    <span class="arrow highlight">&rarr;</span>
                                    <div>
                                        <div class="obj-node grey-node">F</div>
                                    </div>
                                </div>
                            </div>
                            <hr style="border:none;border-top:1px solid var(--border);margin:16px 0">
                            <div>
                                <div
                                    style="font-family:'JetBrains Mono';font-size:11px;color:var(--text-muted);margin-bottom:8px">
                                    Round 5: E, F → 无子指针 → 全部变黑</div>
                                <div class="graph-row">
                                    <div>
                                        <div class="obj-node black-node">A</div>
                                    </div>
                                    <span class="arrow" style="margin:0 4px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node black-node">B</div>
                                    </div>
                                    <span class="arrow" style="margin:0 4px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node black-node">C</div>
                                    </div>
                                    <span class="arrow" style="margin:0 4px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node black-node">D</div>
                                    </div>
                                    <span class="arrow" style="margin:0 4px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node black-node">E</div>
                                    </div>
                                    <span class="arrow" style="margin:0 4px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node black-node">F</div>
                                    </div>
                                </div>
                                <div class="label-sm" style="margin-top:8px;color:var(--accent)">队列空了 &mdash; 标记完成!
                                </div>
                            </div>
                            <hr style="border:none;border-top:1px solid var(--border);margin:16px 0">
                            <div style="text-align:center">
                                <div class="graph-row" style="justify-content:center">
                                    <div>
                                        <div class="obj-node dead-node">G</div>
                                    </div>
                                    <span class="arrow" style="margin:0 16px">&nbsp;</span>
                                    <div>
                                        <div class="obj-node dead-node">H</div>
                                    </div>
                                </div>
                                <div class="label-sm" style="color:var(--red)">标记结束后仍为白色 = 垃圾!</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Phase 3: STW Mark Termination -->
            <div class="phase right">
                <div class="phase-marker">
                    <div class="marker-dot stw">3</div>
                </div>
                <div class="text-panel">
                    <div class="phase-tag stw">STW &mdash; 约 0.1ms</div>
                    <div class="phase-title">标记终止 Mark Termination</div>
                    <div class="phase-desc">
                        <strong>第二次短暂暂停应用。</strong><br><br>
                        这次做收尾工作:<br><br>
                        <strong style="color:#ef4444">① 排空工作队列</strong><br>
                        确保最后几个灰色对象也变黑,没有遗漏。<br><br>
                        <strong style="color:#ef4444">② 关闭写屏障</strong><br>
                        标记已经结束,不再需要监控指针变化了。关了写屏障,应用能跑得更快。<br><br>
                        <strong style="color:#ef4444">③ 重置 GC 状态</strong><br>
                        清除标记位,计算下一轮 GC 触发阈值(pacer)。<br><br>
                        <span style="color:var(--text-muted)">为什么必须暂停?<br>关写屏障 + 清状态必须原子完成,不能一边关一边应用还在用。</span>
                    </div>
                </div>
                <div class="viz-panel">
                    <div class="viz-card stw-card">
                        <div style="text-align:center;margin-bottom:16px">
                            <span
                                style="font-family:'JetBrains Mono';font-size:11px;color:var(--red);letter-spacing:2px">APPLICATION
                                PAUSED — FINAL CLEANUP</span>
                        </div>
                        <div class="obj-graph">
                            <div style="display:flex;flex-direction:column;gap:20px">
                                <!-- Checklist -->
                                <div
                                    style="display:flex;align-items:center;gap:12px;padding:14px 18px;background:rgba(239,68,68,0.06);border:1px solid rgba(239,68,68,0.15);border-radius:10px">
                                    <span style="font-size:18px">&#9989;</span>
                                    <span style="font-size:14px">排空工作队列(最后灰色 → 黑色)</span>
                                </div>
                                <div
                                    style="display:flex;align-items:center;gap:12px;padding:14px 18px;background:rgba(239,68,68,0.06);border:1px solid rgba(239,68,68,0.15);border-radius:10px">
                                    <span style="font-size:18px">&#9989;</span>
                                    <span style="font-size:14px">关闭写屏障 Write Barrier OFF</span>
                                </div>
                                <div
                                    style="display:flex;align-items:center;gap:12px;padding:14px 18px;background:rgba(239,68,68,0.06);border:1px solid rgba(239,68,68,0.15);border-radius:10px">
                                    <span style="font-size:18px">&#9989;</span>
                                    <span style="font-size:14px">重置标记位,计算下轮 GC 阈值</span>
                                </div>
                            </div>
                            <div style="margin-top:24px">
                                <div class="graph-row" style="justify-content:center">
                                    <div>
                                        <div class="obj-node black-node">A</div>
                                    </div>
                                    <div>
                                        <div class="obj-node black-node">B</div>
                                    </div>
                                    <div>
                                        <div class="obj-node black-node">C</div>
                                    </div>
                                    <div>
                                        <div class="obj-node black-node">D</div>
                                    </div>
                                    <div>
                                        <div class="obj-node black-node">E</div>
                                    </div>
                                    <div>
                                        <div class="obj-node black-node">F</div>
                                    </div>
                                </div>
                                <div class="label-sm" style="color:var(--accent);margin-top:8px">全部黑色 = 确认存活</div>
                                <div class="graph-row" style="justify-content:center;margin-top:16px">
                                    <div>
                                        <div class="obj-node dead-node" style="opacity:0.3">G</div>
                                    </div>
                                    <div>
                                        <div class="obj-node dead-node" style="opacity:0.3">H</div>
                                    </div>
                                </div>
                                <div class="label-sm" style="color:var(--red);margin-top:8px">仍为白色 = 即将被回收</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Phase 4: Concurrent Sweep -->
            <div class="phase left">
                <div class="phase-marker">
                    <div class="marker-dot sweep">4</div>
                </div>
                <div class="text-panel">
                    <div class="phase-tag sweep-tag">并发 &mdash; 与应用并行</div>
                    <div class="phase-title">并发清扫 Concurrent Sweep</div>
                    <div class="phase-desc">
                        <strong>应用再次恢复运行</strong>,同时后台清扫白色对象。<br><br>
                        <strong style="color:var(--accent3)">清扫逻辑非常简单:</strong><br>
                        遍历所有内存 span,把仍然标记为白色的对象释放回空闲链表。<br><br>
                        <strong>Lazy Sweep(懒清扫):</strong><br>
                        当应用分配新内存时,如果踩到还没清扫的 span,会顺手帮忙清扫。这样大部分清扫工作在 GC 结束后的短时间窗口内完成,不会堆积到下一轮 GC。
                    </div>
                    <div
                        style="margin-top:20px;padding:16px;background:rgba(16,185,129,0.06);border:1px solid rgba(16,185,129,0.15);border-radius:10px;font-size:14px;color:var(--text-muted)">
                        <strong style="color:var(--accent3)">清扫完成后:</strong><br>
                        内存全部干净,等待下一轮 GC 触发(通常当堆大小增长到上次的 2 倍时)。
                    </div>
                </div>
                <div class="viz-panel">
                    <div class="viz-card sweep-card">
                        <div style="text-align:center;margin-bottom:16px">
                            <span
                                style="font-family:'JetBrains Mono';font-size:11px;color:var(--accent3);letter-spacing:2px">APPLICATION
                                RUNNING + SWEEPING</span>
                        </div>
                        <div class="obj-graph">
                            <div class="graph-row" style="justify-content:center">
                                <div>
                                    <div class="obj-node black-node">A</div>
                                </div>
                                <div>
                                    <div class="obj-node black-node">B</div>
                                </div>
                                <div>
                                    <div class="obj-node black-node">C</div>
                                </div>
                                <div>
                                    <div class="obj-node black-node">D</div>
                                </div>
                                <div>
                                    <div class="obj-node black-node">E</div>
                                </div>
                                <div>
                                    <div class="obj-node black-node">F</div>
                                </div>
                            </div>
                            <div class="label-sm" style="color:var(--accent);margin:8px 0 20px">黑色对象 &mdash; 安全,继续使用
                            </div>

                            <div
                                style="position:relative;text-align:center;padding:24px;border:2px dashed rgba(239,68,68,0.3);border-radius:12px;background:rgba(239,68,68,0.03)">
                                <div class="graph-row" style="justify-content:center">
                                    <div>
                                        <div class="obj-node dead-node" style="opacity:0.2">G</div>
                                    </div>
                                    <span class="arrow" style="margin:0 24px;color:var(--red)">&nbsp;</span>
                                    <div>
                                        <div class="obj-node dead-node" style="opacity:0.2">H</div>
                                    </div>
                                </div>
                                <div
                                    style="font-family:'JetBrains Mono';font-size:12px;color:var(--red);margin-top:12px;opacity:0.8">
                                    &#128465; 释放回空闲内存池
                                </div>
                            </div>

                            <!-- Before / After -->
                            <div
                                style="display:grid;grid-template-columns:1fr auto 1fr;gap:16px;align-items:center;margin-top:24px">
                                <div
                                    style="padding:14px;background:var(--bg);border:1px solid var(--border);border-radius:10px;text-align:center">
                                    <div
                                        style="font-family:'JetBrains Mono';font-size:10px;color:var(--text-muted);margin-bottom:6px">
                                        清扫前</div>
                                    <div style="font-size:20px;font-family:'JetBrains Mono';color:var(--text)">8 对象
                                    </div>
                                    <div style="font-size:11px;color:var(--red);margin-top:4px">含 2 个垃圾</div>
                                </div>
                                <div style="font-family:'JetBrains Mono';font-size:24px;color:var(--accent3)">&rarr;
                                </div>
                                <div
                                    style="padding:14px;background:var(--bg);border:1px solid var(--border);border-radius:10px;text-align:center">
                                    <div
                                        style="font-family:'JetBrains Mono';font-size:10px;color:var(--text-muted);margin-bottom:6px">
                                        清扫后</div>
                                    <div style="font-size:20px;font-family:'JetBrains Mono';color:var(--accent3)">6 对象
                                    </div>
                                    <div style="font-size:11px;color:var(--accent3);margin-top:4px">全部存活</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

        </div><!-- end timeline -->

        <!-- Summary -->
        <div class="summary">
            <h2>全流程总览</h2>
            <div class="summary-grid">
                <div class="summary-card">
                    <div class="num red">2 次</div>
                    <div class="desc">STW 暂停次数<br>标记准备 + 标记终止</div>
                </div>
                <div class="summary-card">
                    <div class="num cyan">
                        < 1ms</div>
                            <div class="desc">每次 STW 耗时<br>只做开关操作,不做遍历</div>
                    </div>
                    <div class="summary-card">
                        <div class="num green">3 色</div>
                        <div class="desc">白 / 灰 / 黑<br>标记状态三色标记法</div>
                    </div>
                    <div class="summary-card">
                        <div class="num yellow">1 个</div>
                        <div class="desc">写屏障 Write Barrier<br>并发标记期的唯一保障</div>
                    </div>
                </div>

                <div
                    style="margin-top:40px;padding:24px;background:var(--bg);border:1px solid var(--border);border-radius:12px">
                    <div style="display:flex;align-items:center;gap:16px;margin-bottom:16px">
                        <span style="font-size:28px">&#128161;</span>
                        <span style="font-size:1.1rem;font-weight:600">核心设计思想</span>
                    </div>
                    <div style="color:var(--text-muted);font-size:0.95rem;line-height:2">
                        Go GC 的设计目标是 <strong
                            style="color:var(--accent)">极低延迟</strong>,而不是极致吞吐。所以它把所有重活(遍历对象图、回收内存)都放到<strong>并发阶段</strong>,而两个
                        STW 阶段只做最轻量的"开关"操作——开/关写屏障、扫描栈根、清理状态。这就是为什么 Go 程序的 GC 暂停时间通常控制在 <strong
                            style="color:var(--accent)">&lt; 500 微秒</strong>以内。
                    </div>
                </div>
            </div>

        </div>

</body>

</html>
不太满意,让Mimo用图像展示

121fa9712a0502077445338f1dea4db1
效果还不错,UI比较炫酷,并且会展示每秒Token消耗等信息

又问了一个Map的底层原理,这里还是用html展示图像
8eb1cf2f1515ed2cc6f7834385fb138d

还想问的时候显示对话达到上限,需要新开,每次体验都是30分钟

贴一下申请链接:https://platform.xiaomimimo.com/ultraspeed

posted @ 2026-06-29 11:53  haojingwu  阅读(11)  评论(0)    收藏  举报