Goroutine leak profile

고루틴 누수 프로파일

Find goroutines that can never be unblocked in a dedicated profile.

···
html
<div class="v"><header><b>GOROUTINE LEAK PROFILE</b><span id="state"></span></header><main><div class="leak"><div class="workers"><div id="worker1">G1: send</div><div id="worker2">G2: send</div><div id="receiver">receiver</div></div><div class="profile"><b>PROFILE</b><span id="profile"></span></div></div></main><footer>unreachable channel leaves senders blocked</footer></div>
css
.v{width:min(92vw,660px);height:min(86vh,310px);box-sizing:border-box;padding:clamp(9px,2.5vmin,18px);border:1px solid var(--line);border-radius:14px;background:var(--surface);display:flex;flex-direction:column;gap:7px;color:var(--fg);font:500 clamp(15px,3.2vmin,17px)/1.25 var(--font-sans, sans-serif)}.v header,.v footer{display:flex;justify-content:space-between;align-items:center;gap:8px;white-space:nowrap}.v header b{color:var(--accent);font-size:.9em}.v header span,.v footer{color:var(--muted);font-size:.82em}.v main{flex:1;min-height:0;position:relative;overflow:hidden}.v .mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}.v .active{background:var(--accent)!important;color:var(--bg)!important;border-color:var(--accent)!important}.v .muted{opacity:.28} .leak{height:100%;display:flex;align-items:center;gap:8px}.workers{width:59%;display:flex;flex-direction:column;gap:5px}.workers div,.profile{border:1px solid var(--line);border-radius:6px;padding:7px;font:600 clamp(12px,2.7vmin,16px) var(--font-sans, sans-serif)}.workers div.stuck{border-color:var(--accent-2);color:var(--accent-2)}.profile{width:41%;min-height:55%;box-sizing:border-box;display:flex;flex-direction:column;justify-content:center;gap:8px;text-align:center}.profile b{color:var(--accent)}.profile span{font-size:1em}
js
let n=0;function draw(){const stuck=n>=1;for(const id of ["worker1","worker2"])document.getElementById(id).classList.toggle("stuck",stuck);document.getElementById("receiver").textContent=stuck?"receiver: gone":"receiver: active";document.getElementById("profile").textContent=n===2?"G1 · G2 leaked":stuck?"GC checks reachability":"0 leaked";document.getElementById("state").textContent=["running","blocked","detected"][n];n=(n+1)%3}draw();setInterval(draw,1000)

Go 1.27 provides a goroutineleak profile for goroutines permanently blocked on channels or synchronization primitives. For example, a sender to an unbuffered channel cannot continue after its receiver exits early.

The detector uses garbage-collector reachability, so it does not catch every leak. A primitive still reachable from a global variable, or a goroutine blocked on network I/O, may escape this check.

When to use

Use it to distinguish normal waiting from permanently stranded goroutines.

Open as page ↗