#!/usr/bin/env -S v -enable-globals run import rand import os import time __global ( bizmodels shared map[string]BizModel ) pub struct SubItem { pub mut: name string intlist []int intstr []string } pub struct BizModel { pub mut: name string intlist []int intstr []string mymap map[string]SubItem } pub fn biz_model_example(name string) BizModel { mut biz_model := BizModel{ name: name intlist: []int{len: 10, init: rand.intn(100) or { 0 }} intstr: []string{len: 10, init: rand.string(5)} mymap: map[string]SubItem{} } for i in 0 .. 100 { sub_item := SubItem{ name: 'SubItem ${i}' intlist: []int{len: 5, init: rand.intn(50) or { 0 }} intstr: []string{len: 5, init: rand.string(3)} } biz_model.mymap['item_${i}'] = sub_item } return biz_model } pub fn get(name string) !BizModel { rlock bizmodels { if ! (name in bizmodels) { return error("can't find bizmodel: ${name}") } return bizmodels[name] or { panic("bug") } } return error("bug") } pub fn getset(name string) BizModel { lock bizmodels { if ! (name in bizmodels) { set(biz_model_example(name)) } return bizmodels[name] or { panic("bug") } } return BizModel{} //weird we need to do this } pub fn set(bizmodel BizModel) { lock bizmodels { bizmodels[bizmodel.name] = bizmodel } } fn fill_biz_models(nr int) { for i in 0 .. nr { getset("bm${i}") } rlock bizmodels{ //check we have enough bizmodels in mem assert bizmodels.len == nr } } fn get_memory_usage() i64 { pid := os.getpid() res := os.execute('ps -o rss= -p ${pid}') return res.output.trim_space().i64() } fn main() { sw := time.new_stopwatch() nr:=100 nr_new :=100000 //make small changes, the garbage collector should keep it clean fill_biz_models(nr) memory_usage_1 := get_memory_usage() println('Memory usage after creating ${nr} BizModels: ${memory_usage_1} KB') println('Time taken: ${sw.elapsed().milliseconds()} ms') for _ in 0 .. nr_new { currentnr:=rand.intn(nr-1) or {panic(err)} mut new_model:= get("bm${currentnr}")! //new_model.intlist = new_model.intlist.map(it + rand.intn(10) or { 0 }) new_model.intstr = new_model.intstr.map(it + rand.string(2)) mut new_model2:= get("bm${currentnr}")! assert new_model2.intstr != new_model.intstr //should be different because was not a reference set(new_model) mut new_model3:= get("bm${currentnr}")! assert new_model3.intstr == new_model.intstr //should be different because was not a reference } rlock bizmodels{ //check we have enough bizmodels in mem assert bizmodels.len == nr } println("wait 1 sec") //lets make sure garbage collector works time.sleep(1 * time.second) memory_usage_2 := get_memory_usage() println('Memory usage after creating ${nr_new} random BizModels: ${memory_usage_2} KB') println('Time taken: ${sw.elapsed().milliseconds()} ms') println("QUESTION: why does memory go up?, we didn't add to the memory should have been equal...") }