gocore: distinguish released memory

Split up the free span space into 2 categories, the space which we
have released back to the OS vs the space we haven't.

Change-Id: I897c57a10e5cb4ab7321711fece8addcf5f4ab19
Reviewed-on: https://go-review.googlesource.com/92417
Reviewed-by: Austin Clements <austin@google.com>
diff --git a/gocore/process.go b/gocore/process.go
index 2e061c8..de034c8 100644
--- a/gocore/process.go
+++ b/gocore/process.go
@@ -254,6 +254,7 @@
 	allspans := mheap.Field("allspans")
 	var allSpanSize int64
 	var freeSpanSize int64
+	var releasedSpanSize int64
 	var manualSpanSize int64
 	var inUseSpanSize int64
 	var allocSize int64
@@ -320,6 +321,8 @@
 			}
 		case spanFree:
 			freeSpanSize += spanSize
+			nReleased := int64(s.Field("npreleased").Uintptr())
+			releasedSpanSize += nReleased * pageSize
 		case spanDead:
 			// These are just deallocated span descriptors. They use no heap.
 		case spanManual:
@@ -347,7 +350,10 @@
 				&Stats{"alloc", manualAllocSize, nil},
 				&Stats{"free", manualFreeSize, nil},
 			}},
-			&Stats{"free spans", freeSpanSize, nil},
+			&Stats{"free spans", freeSpanSize, []*Stats{
+				&Stats{"retained", freeSpanSize - releasedSpanSize, nil},
+				&Stats{"released", releasedSpanSize, nil},
+			}},
 		}},
 		&Stats{"ptr bitmap", bitmap, nil},
 		&Stats{"span table", spanTable, nil},