@@ -14,6 +14,13 @@ import (
14
14
15
15
// Statistics.
16
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.
17
24
type mstats struct {
18
25
// General statistics.
19
26
alloc uint64 // bytes allocated and not yet freed
@@ -24,18 +31,36 @@ type mstats struct {
24
31
nfree uint64 // number of frees
25
32
26
33
// Statistics about malloc heap.
27
- // protected by mheap.lock
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.
28
39
heap_alloc uint64 // bytes allocated and not yet freed (same as alloc above)
29
- heap_sys uint64 // bytes obtained from system
40
+ heap_sys uint64 // virtual address space obtained from system
30
41
heap_idle uint64 // bytes in idle spans
31
42
heap_inuse uint64 // bytes in non-idle spans
32
43
heap_released uint64 // bytes released to the os
33
44
heap_objects uint64 // total number of allocated objects
34
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
+
35
60
// Statistics about allocation of low-level fixed-size structures.
36
61
// Protected by FixAlloc locks.
37
- stacks_inuse uint64 // this number is included in heap_inuse above
38
- stacks_sys uint64 // always 0 in mstats
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
39
64
mspan_inuse uint64 // mspan structures
40
65
mspan_sys uint64
41
66
mcache_inuse uint64 // mcache structures
@@ -64,7 +89,7 @@ type mstats struct {
64
89
nfree uint64
65
90
}
66
91
67
- // Statistics below here are not exported to Go directly.
92
+ // Statistics below here are not exported to MemStats directly.
68
93
69
94
tinyallocs uint64 // number of tiny allocations that didn't cause actual allocation; not exported to go directly
70
95
@@ -118,58 +143,266 @@ var memstats mstats
118
143
// A MemStats records statistics about the memory allocator.
119
144
type MemStats struct {
120
145
// General statistics.
121
- Alloc uint64 // bytes allocated and not yet freed
122
- TotalAlloc uint64 // bytes allocated (even if freed)
123
- Sys uint64 // bytes obtained from system (sum of XxxSys below)
124
- Lookups uint64 // number of pointer lookups
125
- Mallocs uint64 // number of mallocs
126
- Frees uint64 // number of frees
127
-
128
- // Main allocation heap statistics.
129
- HeapAlloc uint64 // bytes allocated and not yet freed (same as Alloc above)
130
- HeapSys uint64 // bytes obtained from system
131
- HeapIdle uint64 // bytes in idle spans
132
- HeapInuse uint64 // bytes in non-idle span
133
- HeapReleased uint64 // bytes released to the OS
134
- HeapObjects uint64 // total number of allocated objects
135
-
136
- // Low-level fixed-size structure allocator statistics.
137
- // Inuse is bytes used now.
138
- // Sys is bytes obtained from system.
139
- StackInuse uint64 // bytes used by stack allocator
140
- StackSys uint64
141
- MSpanInuse uint64 // mspan structures
142
- MSpanSys uint64
143
- MCacheInuse uint64 // mcache structures
144
- MCacheSys uint64
145
- BuckHashSys uint64 // profiling bucket hash table
146
- GCSys uint64 // GC metadata
147
- OtherSys uint64 // other system allocations
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
148
324
149
325
// Garbage collector statistics.
150
- NextGC uint64 // next collection will happen when HeapAlloc ≥ this amount
151
- LastGC uint64 // end time of last collection (nanoseconds since 1970)
152
- PauseTotalNs uint64
153
- PauseNs [256 ]uint64 // circular buffer of recent GC pause durations, most recent at [(NumGC+255)%256]
154
- PauseEnd [256 ]uint64 // circular buffer of recent GC pause end times
155
- NumGC uint32
156
- GCCPUFraction float64 // fraction of CPU time used by GC
157
- EnableGC bool
158
- DebugGC bool
159
-
160
- // Per-size allocation statistics.
161
- // 61 is NumSizeClasses in the C code.
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.
162
394
BySize [61 ]struct {
163
395
Size uint32
164
396
Mallocs uint64
165
397
Frees uint64
166
398
}
167
399
}
168
400
169
- // Size of the trailing by_size array differs between Go and C ,
401
+ // Size of the trailing by_size array differs between mstats and MemStats ,
170
402
// and all data after by_size is local to runtime, not exported.
171
- // NumSizeClasses was changed, but we cannot change Go struct because of backward compatibility.
172
- // sizeof_C_MStats is what C thinks about size of Go struct.
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{}).
173
406
var sizeof_C_MStats = unsafe .Offsetof (memstats .by_size ) + 61 * unsafe .Sizeof (memstats .by_size [0 ])
174
407
175
408
func init () {
@@ -181,6 +414,11 @@ func init() {
181
414
}
182
415
183
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.
184
422
func ReadMemStats (m * MemStats ) {
185
423
stopTheWorld ("read mem stats" )
186
424
@@ -194,8 +432,9 @@ func ReadMemStats(m *MemStats) {
194
432
func readmemstats_m (stats * MemStats ) {
195
433
updatememstats (nil )
196
434
197
- // Size of the trailing by_size array differs between Go and C,
198
- // NumSizeClasses was changed, but we cannot change Go struct because of backward compatibility.
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.
199
438
memmove (unsafe .Pointer (stats ), unsafe .Pointer (& memstats ), sizeof_C_MStats )
200
439
201
440
// Stack numbers are part of the heap numbers, separate those out for user consumption
0 commit comments