-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathex01_retention_test.go
More file actions
40 lines (29 loc) · 1.18 KB
/
ex01_retention_test.go
File metadata and controls
40 lines (29 loc) · 1.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package garbagecollector
import (
"reflect"
"testing"
"unsafe"
)
func TestExtractMetadataRetention(t *testing.T) {
MetadataCache = nil // reset
// 1. Create a massive fake image (1MB)
massiveImage := make([]byte, 1024*1024)
// 2. Run the extraction
ExtractMetadata(massiveImage)
if len(MetadataCache) != 1 {
t.Fatalf("Cache should have 1 item")
}
cachedHeader := MetadataCache[0]
if len(cachedHeader) != 64 {
t.Fatalf("Expected 64 bytes, got %d", len(cachedHeader))
}
// 3. The true test of retention: Are they point to the same backing array?
// We use `unsafe` and reflection to grab the raw memory pointers of the slices.
ptrMassive := (*reflect.SliceHeader)(unsafe.Pointer(&massiveImage)).Data
ptrCached := (*reflect.SliceHeader)(unsafe.Pointer(&cachedHeader)).Data
// If the user used `massiveImage[:64]`, these pointers are mathematically identical!
// If they used `copy`, `make([]byte, 64)` allocated memory cleanly elsewhere on the heap.
if ptrMassive == ptrCached {
t.Fatalf("FAILED: Memory Retention Detected! The cached subslice points directly to the 1MB underlying array! The GC can never free the image. You must explicitly allocate and copy().")
}
}