我有一张地图
myMap := map[string]string
myMap['hello'] = 'world'
myMap['foo'] = 'bar'
当我从myMap中删除一个元素时,
delete(myMap['hello'])
立即释放内存还是在垃圾收集器运行后释放内存。
如果在运行垃圾收集器后释放内存,运行runtime.GC()
是否会立即清理内存。
runtime.GC()
资源还饿吗?或者可以在每个runtime.GC()
函数
delete()
更新2:
忘记我的程序做什么(基本上更新1)
请查看此链接http://play.golang.org/p/Wb8-4qWyf4
每10微秒左右有一个子程序添加到Map
每1微秒从地图中删除一个子程序(比添加快10倍)
在本地计算机上运行此程序,您会发现它继续占用更多内存并且缓慢占用更多内存。 (慢慢地因为我增加了一个睡眠时间,否则计算机会挂起)
更新1
我的程序每分钟从数据库中获取5000行数据,并将其存储在名为datastore的映射中
有100个子程序在运行,它们处理来自数据存储区的每一行。处理一行(不到一秒)需要很长时间
如果数据处理成功,则会从数据存储中删除“delete()”,但在下一分钟内,将获取5000并将其添加到数据存储区。
我在数据存储区中保留最多20,000行。哪个不多(最多200 MB)
在处理了数百万行之后,应用程序开始占用100%的RAM并在最后被kernal杀死。
如果delete()立即清除内存,则不应该发生这种情况。
答案 0 :(得分:1)
您只执行一次deleter
。此外,map
访问权限不是并发安全的,因此您需要在代码周围添加互斥锁。
这是一个不会随时间增长的修复:http://play.golang.org/p/GWQ2hJiySP
package main
import (
"fmt"
"sync"
"time"
)
var datastore = make(map[int64]string)
var m sync.Mutex
func adder() {
var count int64 = 0
for {
m.Lock()
datastore[count] = "kjnbhjsdhgvsaghbsdbasjsabjhsabasbdjashdbashdbjasbdhasbdjbdjbdjhabjds"
m.Unlock()
count++
time.Sleep(10 * time.Microsecond)
}
}
func deleter() {
for {
m.Lock()
for key, _ := range datastore {
delete(datastore, key)
time.Sleep(1 * time.Microsecond)
}
m.Unlock()
}
}
func main() {
// Start adding stuff to datastore (with MORE sleep time = 10 Microsecond)
go adder()
// Wait for some time
time.Sleep(1 * time.Second)
// Start deleting stuff from datastore (With LESS sleep time = 1 Microsecond)
go deleter()
time.Sleep(1 * time.Hour)
fmt.Println("Done")
}
我已将锁定放在整个循环的deleter
周围。它应该只在delete
附近,但是,您不应该使用范围删除条目,因为修改映射可以改变迭代的顺序,因此不应该在实际中使用此结构生活计划。