github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/src/runtime/mstats.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Memory statistics 6 7 package runtime 8 9 import ( 10 "runtime/internal/atomic" 11 "runtime/internal/sys" 12 "unsafe" 13 ) 14 15 // Statistics. 16 // If you edit this structure, also edit type MemStats below. 17 // Their layouts must match exactly. 18 // 19 // For detailed descriptions see the documentation for MemStats. 20 // Fields that differ from MemStats are further documented here. 21 // 22 // Many of these fields are updated on the fly, while others are only 23 // updated when updatememstats is called. 24 type mstats struct { 25 // General statistics. 26 alloc uint64 // bytes allocated and not yet freed 27 total_alloc uint64 // bytes allocated (even if freed) 28 sys uint64 // bytes obtained from system (should be sum of xxx_sys below, no locking, approximate) 29 nlookup uint64 // number of pointer lookups 30 nmalloc uint64 // number of mallocs 31 nfree uint64 // number of frees 32 33 // Statistics about malloc heap. 34 // Protected by mheap.lock 35 // 36 // In mstats, heap_sys and heap_inuse includes stack memory, 37 // while in MemStats stack memory is separated out from the 38 // heap stats. 39 heap_alloc uint64 // bytes allocated and not yet freed (same as alloc above) 40 heap_sys uint64 // virtual address space obtained from system 41 heap_idle uint64 // bytes in idle spans 42 heap_inuse uint64 // bytes in non-idle spans 43 heap_released uint64 // bytes released to the os 44 heap_objects uint64 // total number of allocated objects 45 46 // TODO(austin): heap_released is both useless and inaccurate 47 // in its current form. It's useless because, from the user's 48 // and OS's perspectives, there's no difference between a page 49 // that has not yet been faulted in and a page that has been 50 // released back to the OS. We could fix this by considering 51 // newly mapped spans to be "released". It's inaccurate 52 // because when we split a large span for allocation, we 53 // "unrelease" all pages in the large span and not just the 54 // ones we split off for use. This is trickier to fix because 55 // we currently don't know which pages of a span we've 56 // released. We could fix it by separating "free" and 57 // "released" spans, but then we have to allocate from runs of 58 // free and released spans. 59 60 // Statistics about allocation of low-level fixed-size structures. 61 // Protected by FixAlloc locks. 62 stacks_inuse uint64 // this number is included in heap_inuse above; differs from MemStats.StackInuse 63 stacks_sys uint64 // only counts newosproc0 stack in mstats; differs from MemStats.StackSys 64 mspan_inuse uint64 // mspan structures 65 mspan_sys uint64 66 mcache_inuse uint64 // mcache structures 67 mcache_sys uint64 68 buckhash_sys uint64 // profiling bucket hash table 69 gc_sys uint64 70 other_sys uint64 71 72 // Statistics about garbage collector. 73 // Protected by mheap or stopping the world during GC. 74 next_gc uint64 // goal heap_live for when next GC ends; ^0 if disabled 75 last_gc uint64 // last gc (in absolute time) 76 pause_total_ns uint64 77 pause_ns [256]uint64 // circular buffer of recent gc pause lengths 78 pause_end [256]uint64 // circular buffer of recent gc end times (nanoseconds since 1970) 79 numgc uint32 80 gc_cpu_fraction float64 // fraction of CPU time used by GC 81 enablegc bool 82 debuggc bool 83 84 // Statistics about allocation size classes. 85 86 by_size [_NumSizeClasses]struct { 87 size uint32 88 nmalloc uint64 89 nfree uint64 90 } 91 92 // Statistics below here are not exported to MemStats directly. 93 94 tinyallocs uint64 // number of tiny allocations that didn't cause actual allocation; not exported to go directly 95 96 // gc_trigger is the heap size that triggers marking. 97 // 98 // When heap_live ≥ gc_trigger, the mark phase will start. 99 // This is also the heap size by which proportional sweeping 100 // must be complete. 101 gc_trigger uint64 102 103 // heap_live is the number of bytes considered live by the GC. 104 // That is: retained by the most recent GC plus allocated 105 // since then. heap_live <= heap_alloc, since heap_alloc 106 // includes unmarked objects that have not yet been swept (and 107 // hence goes up as we allocate and down as we sweep) while 108 // heap_live excludes these objects (and hence only goes up 109 // between GCs). 110 // 111 // This is updated atomically without locking. To reduce 112 // contention, this is updated only when obtaining a span from 113 // an mcentral and at this point it counts all of the 114 // unallocated slots in that span (which will be allocated 115 // before that mcache obtains another span from that 116 // mcentral). Hence, it slightly overestimates the "true" live 117 // heap size. It's better to overestimate than to 118 // underestimate because 1) this triggers the GC earlier than 119 // necessary rather than potentially too late and 2) this 120 // leads to a conservative GC rate rather than a GC rate that 121 // is potentially too low. 122 // 123 // Whenever this is updated, call traceHeapAlloc() and 124 // gcController.revise(). 125 heap_live uint64 126 127 // heap_scan is the number of bytes of "scannable" heap. This 128 // is the live heap (as counted by heap_live), but omitting 129 // no-scan objects and no-scan tails of objects. 130 // 131 // Whenever this is updated, call gcController.revise(). 132 heap_scan uint64 133 134 // heap_marked is the number of bytes marked by the previous 135 // GC. After mark termination, heap_live == heap_marked, but 136 // unlike heap_live, heap_marked does not change until the 137 // next mark termination. 138 heap_marked uint64 139 } 140 141 var memstats mstats 142 143 // A MemStats records statistics about the memory allocator. 144 type MemStats struct { 145 // General statistics. 146 147 // Alloc is bytes of allocated heap objects. 148 // 149 // This is the same as HeapAlloc (see below). 150 Alloc uint64 151 152 // TotalAlloc is cumulative bytes allocated for heap objects. 153 // 154 // TotalAlloc increases as heap objects are allocated, but 155 // unlike Alloc and HeapAlloc, it does not decrease when 156 // objects are freed. 157 TotalAlloc uint64 158 159 // Sys is the total bytes of memory obtained from the OS. 160 // 161 // Sys is the sum of the XSys fields below. Sys measures the 162 // virtual address space reserved by the Go runtime for the 163 // heap, stacks, and other internal data structures. It's 164 // likely that not all of the virtual address space is backed 165 // by physical memory at any given moment, though in general 166 // it all was at some point. 167 Sys uint64 168 169 // Lookups is the number of pointer lookups performed by the 170 // runtime. 171 // 172 // This is primarily useful for debugging runtime internals. 173 Lookups uint64 174 175 // Mallocs is the cumulative count of heap objects allocated. 176 Mallocs uint64 177 178 // Frees is the cumulative count of heap objects freed. 179 Frees uint64 180 181 // Heap memory statistics. 182 // 183 // Interpreting the heap statistics requires some knowledge of 184 // how Go organizes memory. Go divides the virtual address 185 // space of the heap into "spans", which are contiguous 186 // regions of memory 8K or larger. A span may be in one of 187 // three states: 188 // 189 // An "idle" span contains no objects or other data. The 190 // physical memory backing an idle span can be released back 191 // to the OS (but the virtual address space never is), or it 192 // can be converted into an "in use" or "stack" span. 193 // 194 // An "in use" span contains at least one heap object and may 195 // have free space available to allocate more heap objects. 196 // 197 // A "stack" span is used for goroutine stacks. Stack spans 198 // are not considered part of the heap. A span can change 199 // between heap and stack memory; it is never used for both 200 // simultaneously. 201 202 // HeapAlloc is bytes of allocated heap objects. 203 // 204 // "Allocated" heap objects include all reachable objects, as 205 // well as unreachable objects that the garbage collector has 206 // not yet freed. Specifically, HeapAlloc increases as heap 207 // objects are allocated and decreases as the heap is swept 208 // and unreachable objects are freed. Sweeping occurs 209 // incrementally between GC cycles, so these two processes 210 // occur simultaneously, and as a result HeapAlloc tends to 211 // change smoothly (in contrast with the sawtooth that is 212 // typical of stop-the-world garbage collectors). 213 HeapAlloc uint64 214 215 // HeapSys is bytes of heap memory obtained from the OS. 216 // 217 // HeapSys measures the amount of virtual address space 218 // reserved for the heap. This includes virtual address space 219 // that has been reserved but not yet used, which consumes no 220 // physical memory, but tends to be small, as well as virtual 221 // address space for which the physical memory has been 222 // returned to the OS after it became unused (see HeapReleased 223 // for a measure of the latter). 224 // 225 // HeapSys estimates the largest size the heap has had. 226 HeapSys uint64 227 228 // HeapIdle is bytes in idle (unused) spans. 229 // 230 // Idle spans have no objects in them. These spans could be 231 // (and may already have been) returned to the OS, or they can 232 // be reused for heap allocations, or they can be reused as 233 // stack memory. 234 // 235 // HeapIdle minus HeapReleased estimates the amount of memory 236 // that could be returned to the OS, but is being retained by 237 // the runtime so it can grow the heap without requesting more 238 // memory from the OS. If this difference is significantly 239 // larger than the heap size, it indicates there was a recent 240 // transient spike in live heap size. 241 HeapIdle uint64 242 243 // HeapInuse is bytes in in-use spans. 244 // 245 // In-use spans have at least one object in them. These spans 246 // can only be used for other objects of roughly the same 247 // size. 248 // 249 // HeapInuse minus HeapAlloc esimates the amount of memory 250 // that has been dedicated to particular size classes, but is 251 // not currently being used. This is an upper bound on 252 // fragmentation, but in general this memory can be reused 253 // efficiently. 254 HeapInuse uint64 255 256 // HeapReleased is bytes of physical memory returned to the OS. 257 // 258 // This counts heap memory from idle spans that was returned 259 // to the OS and has not yet been reacquired for the heap. 260 HeapReleased uint64 261 262 // HeapObjects is the number of allocated heap objects. 263 // 264 // Like HeapAlloc, this increases as objects are allocated and 265 // decreases as the heap is swept and unreachable objects are 266 // freed. 267 HeapObjects uint64 268 269 // Stack memory statistics. 270 // 271 // Stacks are not considered part of the heap, but the runtime 272 // can reuse a span of heap memory for stack memory, and 273 // vice-versa. 274 275 // StackInuse is bytes in stack spans. 276 // 277 // In-use stack spans have at least one stack in them. These 278 // spans can only be used for other stacks of the same size. 279 // 280 // There is no StackIdle because unused stack spans are 281 // returned to the heap (and hence counted toward HeapIdle). 282 StackInuse uint64 283 284 // StackSys is bytes of stack memory obtained from the OS. 285 // 286 // StackSys is StackInuse, plus any memory obtained directly 287 // from the OS for OS thread stacks (which should be minimal). 288 StackSys uint64 289 290 // Off-heap memory statistics. 291 // 292 // The following statistics measure runtime-internal 293 // structures that are not allocated from heap memory (usually 294 // because they are part of implementing the heap). Unlike 295 // heap or stack memory, any memory allocated to these 296 // structures is dedicated to these structures. 297 // 298 // These are primarily useful for debugging runtime memory 299 // overheads. 300 301 // MSpanInuse is bytes of allocated mspan structures. 302 MSpanInuse uint64 303 304 // MSpanSys is bytes of memory obtained from the OS for mspan 305 // structures. 306 MSpanSys uint64 307 308 // MCacheInuse is bytes of allocated mcache structures. 309 MCacheInuse uint64 310 311 // MCacheSys is bytes of memory obtained from the OS for 312 // mcache structures. 313 MCacheSys uint64 314 315 // BuckHashSys is bytes of memory in profiling bucket hash tables. 316 BuckHashSys uint64 317 318 // GCSys is bytes of memory in garbage collection metadata. 319 GCSys uint64 320 321 // OtherSys is bytes of memory in miscellaneous off-heap 322 // runtime allocations. 323 OtherSys uint64 324 325 // Garbage collector statistics. 326 327 // NextGC is the target heap size of the next GC cycle. 328 // 329 // The garbage collector's goal is to keep HeapAlloc ≤ NextGC. 330 // At the end of each GC cycle, the target for the next cycle 331 // is computed based on the amount of reachable data and the 332 // value of GOGC. 333 NextGC uint64 334 335 // LastGC is the time the last garbage collection finished, as 336 // nanoseconds since 1970 (the UNIX epoch). 337 LastGC uint64 338 339 // PauseTotalNs is the cumulative nanoseconds in GC 340 // stop-the-world pauses since the program started. 341 // 342 // During a stop-the-world pause, all goroutines are paused 343 // and only the garbage collector can run. 344 PauseTotalNs uint64 345 346 // PauseNs is a circular buffer of recent GC stop-the-world 347 // pause times in nanoseconds. 348 // 349 // The most recent pause is at PauseNs[(NumGC+255)%256]. In 350 // general, PauseNs[N%256] records the time paused in the most 351 // recent N%256th GC cycle. There may be multiple pauses per 352 // GC cycle; this is the sum of all pauses during a cycle. 353 PauseNs [256]uint64 354 355 // PauseEnd is a circular buffer of recent GC pause end times, 356 // as nanoseconds since 1970 (the UNIX epoch). 357 // 358 // This buffer is filled the same way as PauseNs. There may be 359 // multiple pauses per GC cycle; this records the end of the 360 // last pause in a cycle. 361 PauseEnd [256]uint64 362 363 // NumGC is the number of completed GC cycles. 364 NumGC uint32 365 366 // GCCPUFraction is the fraction of this program's available 367 // CPU time used by the GC since the program started. 368 // 369 // GCCPUFraction is expressed as a number between 0 and 1, 370 // where 0 means GC has consumed none of this program's CPU. A 371 // program's available CPU time is defined as the integral of 372 // GOMAXPROCS since the program started. That is, if 373 // GOMAXPROCS is 2 and a program has been running for 10 374 // seconds, its "available CPU" is 20 seconds. GCCPUFraction 375 // does not include CPU time used for write barrier activity. 376 // 377 // This is the same as the fraction of CPU reported by 378 // GODEBUG=gctrace=1. 379 GCCPUFraction float64 380 381 // EnableGC indicates that GC is enabled. It is always true, 382 // even if GOGC=off. 383 EnableGC bool 384 385 // DebugGC is currently unused. 386 DebugGC bool 387 388 // BySize reports per-size class allocation statistics. 389 // 390 // BySize[N] gives statistics for allocations of size S where 391 // BySize[N-1].Size < S ≤ BySize[N].Size. 392 // 393 // This does not report allocations larger than BySize[60].Size. 394 BySize [61]struct { 395 Size uint32 396 Mallocs uint64 397 Frees uint64 398 } 399 } 400 401 // Size of the trailing by_size array differs between mstats and MemStats, 402 // and all data after by_size is local to runtime, not exported. 403 // NumSizeClasses was changed, but we cannot change MemStats because of backward compatibility. 404 // sizeof_C_MStats is the size of the prefix of mstats that 405 // corresponds to MemStats. It should match Sizeof(MemStats{}). 406 var sizeof_C_MStats = unsafe.Offsetof(memstats.by_size) + 61*unsafe.Sizeof(memstats.by_size[0]) 407 408 func init() { 409 var memStats MemStats 410 if sizeof_C_MStats != unsafe.Sizeof(memStats) { 411 println(sizeof_C_MStats, unsafe.Sizeof(memStats)) 412 throw("MStats vs MemStatsType size mismatch") 413 } 414 } 415 416 // ReadMemStats populates m with memory allocator statistics. 417 // 418 // The returned memory allocator statistics are up to date as of the 419 // call to ReadMemStats. This is in contrast with a heap profile, 420 // which is a snapshot as of the most recently completed garbage 421 // collection cycle. 422 func ReadMemStats(m *MemStats) { 423 stopTheWorld("read mem stats") 424 425 systemstack(func() { 426 readmemstats_m(m) 427 }) 428 429 startTheWorld() 430 } 431 432 func readmemstats_m(stats *MemStats) { 433 updatememstats(nil) 434 435 // The size of the trailing by_size array differs between 436 // mstats and MemStats. NumSizeClasses was changed, but we 437 // cannot change MemStats because of backward compatibility. 438 memmove(unsafe.Pointer(stats), unsafe.Pointer(&memstats), sizeof_C_MStats) 439 440 // Stack numbers are part of the heap numbers, separate those out for user consumption 441 stats.StackSys += stats.StackInuse 442 stats.HeapInuse -= stats.StackInuse 443 stats.HeapSys -= stats.StackInuse 444 } 445 446 //go:linkname readGCStats runtime/debug.readGCStats 447 func readGCStats(pauses *[]uint64) { 448 systemstack(func() { 449 readGCStats_m(pauses) 450 }) 451 } 452 453 func readGCStats_m(pauses *[]uint64) { 454 p := *pauses 455 // Calling code in runtime/debug should make the slice large enough. 456 if cap(p) < len(memstats.pause_ns)+3 { 457 throw("short slice passed to readGCStats") 458 } 459 460 // Pass back: pauses, pause ends, last gc (absolute time), number of gc, total pause ns. 461 lock(&mheap_.lock) 462 463 n := memstats.numgc 464 if n > uint32(len(memstats.pause_ns)) { 465 n = uint32(len(memstats.pause_ns)) 466 } 467 468 // The pause buffer is circular. The most recent pause is at 469 // pause_ns[(numgc-1)%len(pause_ns)], and then backward 470 // from there to go back farther in time. We deliver the times 471 // most recent first (in p[0]). 472 p = p[:cap(p)] 473 for i := uint32(0); i < n; i++ { 474 j := (memstats.numgc - 1 - i) % uint32(len(memstats.pause_ns)) 475 p[i] = memstats.pause_ns[j] 476 p[n+i] = memstats.pause_end[j] 477 } 478 479 p[n+n] = memstats.last_gc 480 p[n+n+1] = uint64(memstats.numgc) 481 p[n+n+2] = memstats.pause_total_ns 482 unlock(&mheap_.lock) 483 *pauses = p[:n+n+3] 484 } 485 486 //go:nowritebarrier 487 func updatememstats(stats *gcstats) { 488 if stats != nil { 489 *stats = gcstats{} 490 } 491 for mp := allm; mp != nil; mp = mp.alllink { 492 if stats != nil { 493 src := (*[unsafe.Sizeof(gcstats{}) / 8]uint64)(unsafe.Pointer(&mp.gcstats)) 494 dst := (*[unsafe.Sizeof(gcstats{}) / 8]uint64)(unsafe.Pointer(stats)) 495 for i, v := range src { 496 dst[i] += v 497 } 498 mp.gcstats = gcstats{} 499 } 500 } 501 502 memstats.mcache_inuse = uint64(mheap_.cachealloc.inuse) 503 memstats.mspan_inuse = uint64(mheap_.spanalloc.inuse) 504 memstats.sys = memstats.heap_sys + memstats.stacks_sys + memstats.mspan_sys + 505 memstats.mcache_sys + memstats.buckhash_sys + memstats.gc_sys + memstats.other_sys 506 507 // Calculate memory allocator stats. 508 // During program execution we only count number of frees and amount of freed memory. 509 // Current number of alive object in the heap and amount of alive heap memory 510 // are calculated by scanning all spans. 511 // Total number of mallocs is calculated as number of frees plus number of alive objects. 512 // Similarly, total amount of allocated memory is calculated as amount of freed memory 513 // plus amount of alive heap memory. 514 memstats.alloc = 0 515 memstats.total_alloc = 0 516 memstats.nmalloc = 0 517 memstats.nfree = 0 518 for i := 0; i < len(memstats.by_size); i++ { 519 memstats.by_size[i].nmalloc = 0 520 memstats.by_size[i].nfree = 0 521 } 522 523 // Flush MCache's to MCentral. 524 systemstack(flushallmcaches) 525 526 // Aggregate local stats. 527 cachestats() 528 529 // Scan all spans and count number of alive objects. 530 lock(&mheap_.lock) 531 for _, s := range mheap_.allspans { 532 if s.state != mSpanInUse { 533 continue 534 } 535 if s.sizeclass == 0 { 536 memstats.nmalloc++ 537 memstats.alloc += uint64(s.elemsize) 538 } else { 539 memstats.nmalloc += uint64(s.allocCount) 540 memstats.by_size[s.sizeclass].nmalloc += uint64(s.allocCount) 541 memstats.alloc += uint64(s.allocCount) * uint64(s.elemsize) 542 } 543 } 544 unlock(&mheap_.lock) 545 546 // Aggregate by size class. 547 smallfree := uint64(0) 548 memstats.nfree = mheap_.nlargefree 549 for i := 0; i < len(memstats.by_size); i++ { 550 memstats.nfree += mheap_.nsmallfree[i] 551 memstats.by_size[i].nfree = mheap_.nsmallfree[i] 552 memstats.by_size[i].nmalloc += mheap_.nsmallfree[i] 553 smallfree += mheap_.nsmallfree[i] * uint64(class_to_size[i]) 554 } 555 memstats.nfree += memstats.tinyallocs 556 memstats.nmalloc += memstats.nfree 557 558 // Calculate derived stats. 559 memstats.total_alloc = memstats.alloc + mheap_.largefree + smallfree 560 memstats.heap_alloc = memstats.alloc 561 memstats.heap_objects = memstats.nmalloc - memstats.nfree 562 } 563 564 //go:nowritebarrier 565 func cachestats() { 566 for i := 0; ; i++ { 567 p := allp[i] 568 if p == nil { 569 break 570 } 571 c := p.mcache 572 if c == nil { 573 continue 574 } 575 purgecachedstats(c) 576 } 577 } 578 579 // flushmcache flushes the mcache of allp[i]. 580 // 581 // The world must be stopped. 582 // 583 //go:nowritebarrier 584 func flushmcache(i int) { 585 p := allp[i] 586 if p == nil { 587 return 588 } 589 c := p.mcache 590 if c == nil { 591 return 592 } 593 c.releaseAll() 594 stackcache_clear(c) 595 } 596 597 // flushallmcaches flushes the mcaches of all Ps. 598 // 599 // The world must be stopped. 600 // 601 //go:nowritebarrier 602 func flushallmcaches() { 603 for i := 0; i < int(gomaxprocs); i++ { 604 flushmcache(i) 605 } 606 } 607 608 //go:nosplit 609 func purgecachedstats(c *mcache) { 610 // Protected by either heap or GC lock. 611 h := &mheap_ 612 memstats.heap_scan += uint64(c.local_scan) 613 c.local_scan = 0 614 memstats.tinyallocs += uint64(c.local_tinyallocs) 615 c.local_tinyallocs = 0 616 memstats.nlookup += uint64(c.local_nlookup) 617 c.local_nlookup = 0 618 h.largefree += uint64(c.local_largefree) 619 c.local_largefree = 0 620 h.nlargefree += uint64(c.local_nlargefree) 621 c.local_nlargefree = 0 622 for i := 0; i < len(c.local_nsmallfree); i++ { 623 h.nsmallfree[i] += uint64(c.local_nsmallfree[i]) 624 c.local_nsmallfree[i] = 0 625 } 626 } 627 628 // Atomically increases a given *system* memory stat. We are counting on this 629 // stat never overflowing a uintptr, so this function must only be used for 630 // system memory stats. 631 // 632 // The current implementation for little endian architectures is based on 633 // xadduintptr(), which is less than ideal: xadd64() should really be used. 634 // Using xadduintptr() is a stop-gap solution until arm supports xadd64() that 635 // doesn't use locks. (Locks are a problem as they require a valid G, which 636 // restricts their useability.) 637 // 638 // A side-effect of using xadduintptr() is that we need to check for 639 // overflow errors. 640 //go:nosplit 641 func mSysStatInc(sysStat *uint64, n uintptr) { 642 if sys.BigEndian != 0 { 643 atomic.Xadd64(sysStat, int64(n)) 644 return 645 } 646 if val := atomic.Xadduintptr((*uintptr)(unsafe.Pointer(sysStat)), n); val < n { 647 print("runtime: stat overflow: val ", val, ", n ", n, "\n") 648 exit(2) 649 } 650 } 651 652 // Atomically decreases a given *system* memory stat. Same comments as 653 // mSysStatInc apply. 654 //go:nosplit 655 func mSysStatDec(sysStat *uint64, n uintptr) { 656 if sys.BigEndian != 0 { 657 atomic.Xadd64(sysStat, -int64(n)) 658 return 659 } 660 if val := atomic.Xadduintptr((*uintptr)(unsafe.Pointer(sysStat)), uintptr(-int64(n))); val+n < n { 661 print("runtime: stat underflow: val ", val, ", n ", n, "\n") 662 exit(2) 663 } 664 }