Files
learngo/16-slices/exercises/18-internals-slice-header/main.go

119 lines
3.1 KiB
Go
Raw Normal View History

package main
import (
"fmt"
"runtime"
"runtime/debug"
)
// ---------------------------------------------------------
// EXERCISE: Observe the memory allocations
//
// In this exercise, your goal is to observe the memory allocation
// differences between arrays and slices.
//
// You will create, assign arrays and slices then you will print
// the memory usage of your program on each step.
//
// Please follow the instructions inside the code.
//
//
// EXPECTED OUTPUT
//
// Note that, your memory usage numbers may vary. These are on my
// own system. However, the size of the arrays and slices should be
// the same on your own system as well (if you're on 64-bit machine).
//
//
// [initial memory usage]
// > Memory Usage: 104 KB
// [after declaring an array]
// > Memory Usage: 78235 KB
// [after copying the array]
// > Memory Usage: 156365 KB
// [inside passArray]
// > Memory Usage: 234495 KB
// [after slicings]
// > Memory Usage: 234497 KB
// [inside passSlice]
// > Memory Usage: 234497 KB
//
// Array's size : 80000000 bytes.
// Array2's size: 80000000 bytes.
// Slice1's size: 24 bytes.
// Slice2's size: 24 bytes.
// Slice3's size: 24 bytes.
//
//
// HINTS
//
// I've declared a few functions to help you.
//
// report function:
// - Prints the memory usage.
// - Just call it with a message that matches to the expected output.
//
// passArray function:
// - Accepts a [size]int array, so you can pass it your array.
// - It automatically prints the memory usage.
//
// passSlice function:
// - Accepts an int slice, so you can pass it one of your slices.
// - It automatically prints the memory usage.
//
// ---------------------------------------------------------
const size = 1e7
func main() {
// stops the gc: prevents cleaning up the memory
debug.SetGCPercent(-1)
// run the program to see what this prints
report("initial memory usage")
// 1. allocate an array with 10 million int elements
// this array's size is equal to ~80MB
// hint: use the `size` constant
//
// 2. print the memory usage
// 3. copy the array to a new array (just assign)
// 4. print the memory usage
// 5. pass the array to the passArray function
// 6. convert the one of the arrays to a slice (by slicing)
// 7. slice only the first 1000 elements of the array
// 8. slice only the elements of the array between 1000 and 10000
// 9. print the memory usage
// 10. pass the one of the slices to the passSlice function
// 11. print the sizes of the arrays and slices
// hint: use the unsafe.Sizeof function
}
// observe that passing an array affects the memory usage dramatically
//
// passes [size]int array — about 80MB!
func passArray(items [size]int) {
items[0] = 100
report("inside passArray")
}
// observe that passing a slice doesn't affect the memory usage
//
// only passes 24-bytes of slice header
func passSlice(items []int) {
items[0] = 100
report("inside passSlice")
}
func report(msg string) {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("[%s]\n", msg)
fmt.Printf("\t> Memory Usage: %v KB\n", m.Alloc/1024)
}