delete()是否可以立即释放内存或运行时.GC()需要释放它?

时间:2014-04-05 13:31:12

标签: memory-management garbage-collection go runtime

我有一张地图

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()立即清除内存,则不应该发生这种情况。

1 个答案:

答案 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附近,但是,您不应该使用范围删除条目,因为修改映射可以改变迭代的顺序,因此不应该在实际中使用此结构生活计划。