Golang:致命错误:运行时:内存不足

我试图在Github中使用这个包进行字符串匹配。我的字典是 4 MB。创建 Trie 时,我得到了fatal error: runtime: out of memory. 我正在使用具有 8 GB RAM 和 Golang 版本 1.4.2 的 Ubuntu 14.04。


似乎错误来自第 99 行(现在):m.trie = make([]node, max)


程序停在这一行。


这是错误:


fatal error: runtime: out of memory


runtime stack:

runtime.SysMap(0xc209cd0000, 0x3b1bc0000, 0x570a00, 0x5783f8)

    /usr/local/go/src/runtime/mem_linux.c:149 +0x98

runtime.MHeap_SysAlloc(0x57dae0, 0x3b1bc0000, 0x4296f2)

    /usr/local/go/src/runtime/malloc.c:284 +0x124

runtime.MHeap_Alloc(0x57dae0, 0x1d8dda, 0x10100000000, 0x8)

    /usr/local/go/src/runtime/mheap.c:240 +0x66


goroutine 1 [running]:

runtime.switchtoM()

    /usr/local/go/src/runtime/asm_amd64.s:198 fp=0xc208518a60 sp=0xc208518a58

runtime.mallocgc(0x3b1bb25f0, 0x4d7fc0, 0x0, 0xc20803c0d0)

    /usr/local/go/src/runtime/malloc.go:199 +0x9f3 fp=0xc208518b10 sp=0xc208518a60

runtime.newarray(0x4d7fc0, 0x3a164e, 0x1)

    /usr/local/go/src/runtime/malloc.go:365 +0xc1 fp=0xc208518b48 sp=0xc208518b10

runtime.makeslice(0x4a52a0, 0x3a164e, 0x3a164e, 0x0, 0x0, 0x0)

    /usr/local/go/src/runtime/slice.go:32 +0x15c fp=0xc208518b90 sp=0xc208518b48

github.com/mf/ahocorasick.(*Matcher).buildTrie(0xc2083c7e60, 0xc209860000, 0x26afb, 0x2f555)

    /home/go/ahocorasick/ahocorasick.go:104 +0x28b fp=0xc208518d90 sp=0xc208518b90

github.com/mf/ahocorasick.NewStringMatcher(0xc208bd0000, 0x26afb, 0x2d600, 0x8)

    /home/go/ahocorasick/ahocorasick.go:222 +0x34b fp=0xc208518ec0 sp=0xc208518d90

main.main()

这是 main 函数的内容(取自同一个 repo:test 文件)


var dictionary = InitDictionary()   

var bytes = []byte(""Partial invoice (€100,000, so roughly 40%) for the consignment C27655 we shipped on 15th August to London from the Make Believe Town depot. INV2345 is for the balance.. Customer contact (Sigourney) says they will pay this on the usual credit terms (30 days).")   


var precomputed = ahocorasick.NewStringMatcher(dictionary)// line 66 here

fmt.Println(precomputed.Match(bytes))


呼啦一阵风
浏览 600回答 3
3回答

慕斯709654

您的结构在内存方面非常低效,让我们看看内部结构。但在此之前,快速提醒一些 go 类型所需的空间:布尔值:1 个字节整数:4 字节uintptr:4 字节[N]类型:N*sizeof(type)[]type: 12 + len(slice)*sizeof(type)现在,让我们看看你的结构:type node struct {    root bool        // 1 byte    b []byte         // 12 + len(slice)*1    output bool      // 1 byte    index int        // 4 bytes    counter int      // 4 bytes    child [256]*node // 256*4 = 1024 bytes    fails [256]*node // 256*4 = 1024 bytes    suffix *node     // 4 bytes    fail *node       // 4 bytes}好的,你应该猜到这里发生了什么:每个节点的重量都超过 2KB,这是巨大的!最后,我们将查看用于初始化 trie 的代码:func (m *Matcher) buildTrie(dictionary [][]byte) {    max := 1    for _, blice := range dictionary {        max += len(blice)    }    m.trie = make([]node, max)    // ...}你说你的字典是 4 MB。如果总共是 4MB,那么就意味着在 for 循环结束时,max = 4MB. 它包含 4 MB 不同的单词,然后max = 4MB*avg(word_length).我们将采用第一个场景,最好的一个。您正在初始化一个 4M 节点的切片,每个节点使用 2KB。是的,这需要一个不错的 8GB。您应该查看如何构建您的 trie。从与 Aho-Corasick 算法相关的维基百科页面中,每个节点包含一个字符,因此从根开始最多有 256 个字符,而不是 4MB。一些使其正确的材料:https ://web.archive.org/web/20160315124629/http://www.cs.uku.fi/~kilpelai/BSA05/lectures/slides04.pdf

阿晨1998

该node类型的内存大小为2084字节。我写了一个小程序来演示内存使用情况:https: //play.golang.org/p/szm7AirsDB如您所见,三个字符串(大小为 11(+1) 个字节)dictionary := []string{"fizz", "buzz", "123"}需要 24 MB 内存。如果您的字典有 4 MB 的长度,您将需要大约4000 * 2084 = 8.1 GB内存。因此,您应该尝试减小字典的大小。

catspeake

将资源限制设置为无限制为我工作如果ulimit -a返回 0 运行ulimit -c unlimited也许设置一个真正的大小限制更安全
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go