github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/ramUsageEstimator.go (about) 1 package util 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 // util.RamUsageEstimator.java 9 10 // amd64 system 11 const ( 12 NUM_BYTES_CHAR = 2 // UTF8 uses 1-4 bytes to represent each rune 13 NUM_BYTES_SHORT = 2 14 NUM_BYTES_INT = 8 15 NUM_BYTES_FLOAT = 4 16 NUM_BYTES_LONG = 8 17 18 /* Number of bytes to represent an object reference */ 19 NUM_BYTES_OBJECT_REF = 8 20 21 // Number of bytes to represent an object header (no fields, no alignments). 22 NUM_BYTES_OBJECT_HEADER = 16 23 24 // Number of bytes to represent an array header (no content, but with alignments). 25 NUM_BYTES_ARRAY_HEADER = 24 26 27 // A constant specifying the object alignment boundary inside the 28 // JVM. Objects will always take a full multiple of this constant, 29 // possibly wasting some space. 30 NUM_BYTES_OBJECT_ALIGNMENT = 8 31 ) 32 33 /* Aligns an object size to be the next multiple of NUM_BYTES_OBJECT_ALIGNMENT */ 34 func AlignObjectSize(size int64) int64 { 35 size += NUM_BYTES_OBJECT_ALIGNMENT - 1 36 return size - (size & NUM_BYTES_OBJECT_ALIGNMENT) 37 } 38 39 /* Returns the size in bytes of the object. */ 40 func SizeOf(arr interface{}) int64 { 41 if arr == nil { 42 return 0 43 } 44 switch arr.(type) { 45 case []int64: 46 return AlignObjectSize(NUM_BYTES_ARRAY_HEADER + NUM_BYTES_LONG*int64(len(arr.([]int64)))) 47 case []int16: 48 return AlignObjectSize(NUM_BYTES_ARRAY_HEADER + NUM_BYTES_SHORT*int64(len(arr.([]int16)))) 49 case []byte: 50 return AlignObjectSize(NUM_BYTES_ARRAY_HEADER + int64(len(arr.([]byte)))) 51 default: 52 if t := reflect.TypeOf(arr); t.Kind() == reflect.Slice { 53 var size int64 54 v := reflect.ValueOf(arr) 55 for i := 0; i < v.Len(); i++ { 56 size += v.Index(i).Interface().(Accountable).RamBytesUsed() 57 } 58 return size 59 } 60 fmt.Println("Unknown type:", reflect.TypeOf(arr)) 61 panic("not supported yet") 62 } 63 } 64 65 /* 66 Estimates a "shallow" memory usage of the given object. For slices, 67 this will be the memory taken by slice storage (no subreferences will 68 be followed). For objects, this will be the memory taken by the fields. 69 */ 70 func ShallowSizeOf(obj interface{}) int64 { 71 if obj == nil { 72 return 0 73 } 74 clz := reflect.TypeOf(obj) 75 if clz.Kind() == reflect.Slice { 76 return shallowSizeOfArray(obj) 77 } 78 return ShallowSizeOfInstance(clz) 79 } 80 81 func ShallowSizeOfInstance(clazz reflect.Type) int64 { 82 // TODO later 83 fmt.Printf("[TODO] ShallowSizeOfInstance(%v)\n", clazz) 84 return 0 85 } 86 87 /* Return shallow size of any array */ 88 func shallowSizeOfArray(arr interface{}) int64 { 89 size := int64(NUM_BYTES_ARRAY_HEADER) 90 v := reflect.ValueOf(arr) 91 if length := v.Len(); length > 0 { 92 switch v.Kind() { 93 case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, 94 reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, 95 reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, 96 reflect.Float64, reflect.Complex64, reflect.Complex128: 97 // primitive type 98 size += int64(length) * int64(v.Elem().Type().Size()) 99 default: 100 size += int64(length * NUM_BYTES_OBJECT_REF) 101 } 102 } 103 return AlignObjectSize(size) 104 }