Go的map中删除子map,内存会自动释放吗?

栏目: Go · 发布时间: 7年前

内容简介:在Go中,map中存放map,上层map执行delete,子层map占用的内存会释放,无需手动先释放子map内存,再在上层map执行删除。在C++中,如果使用了map包含map的数据结构,当要释放上层map的某一项时,需要手动释放对应的子map占用的内存,而在Go中,垃圾回收让内存管理变得如此简单。结果

结论

Go 中,map中存放map,上层map执行delete,子层map占用的内存会释放,无需手动先释放子map内存,再在上层map执行删除。

实验

在C++中,如果使用了map包含map的数据结构,当要释放上层map的某一项时,需要手动释放对应的子map占用的内存,而在Go中,垃圾回收让内存管理变得如此简单。

package main

import (
    "log"
    "runtime"
)

var lastTotalFreed uint64
var intMap map[int]int
var cnt = 8192

func main() {
    printMemStats()

    initMap()
    runtime.GC()
    printMemStats()

    log.Println(len(intMap))
    for i := 0; i < cnt; i++ {
        delete(intMap, i)
    }
    log.Println(len(intMap))

    runtime.GC()
    printMemStats()

    intMap = nil
    runtime.GC()
    printMemStats()
}

func initMap() {
    intMap = make(map[int]int, cnt)

    for i := 0; i < cnt; i++ {
        intMap[i] = i
    }
}

func printMemStats() {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    log.Printf("Alloc = %v TotalAlloc = %v  Just Freed = %v Sys = %v NumGC = %v\n",
        m.Alloc/1024, m.TotalAlloc/1024, ((m.TotalAlloc-m.Alloc)-lastTotalFreed)/1024, m.Sys/1024, m.NumGC)

    lastTotalFreed = m.TotalAlloc - m.Alloc
}

结果

2018/09/29 20:09:25 Alloc = 65 TotalAlloc = 65  Just Freed = 0 Sys = 1700 NumGC = 0
2018/09/29 20:09:25 Alloc = 387 TotalAlloc = 391  Just Freed = 3 Sys = 3076 NumGC = 1
2018/09/29 20:09:25 8192
2018/09/29 20:09:25 0
2018/09/29 20:09:25 Alloc = 387 TotalAlloc = 392  Just Freed = 1 Sys = 3140 NumGC = 2
2018/09/29 20:09:25 Alloc = 74 TotalAlloc = 394  Just Freed = 314 Sys = 3140 NumGC = 3
package main

import (
    "log"
    "runtime"
)

var intMapMap map[int]map[int]int

var cnt = 1024
var lastTotalFreed uint64 // size of last memory has been freed

func main() {
    // 1
    printMemStats()

    // 2
    initMapMap()
    runtime.GC()
    printMemStats()

    // 3
    fillMapMap()
    runtime.GC()
    printMemStats()

    // 4
    log.Println(len(intMapMap))
    for i := 0; i < cnt; i++ {
        delete(intMapMap, i)
    }
    log.Println(len(intMapMap))
    runtime.GC()
    printMemStats()

    // 5
    intMapMap = nil
    runtime.GC()
    printMemStats()
}

func initMapMap() {
    intMapMap = make(map[int]map[int]int, cnt)
    for i := 0; i < cnt; i++ {
        intMapMap[i] = make(map[int]int, cnt)
    }
}

func fillMapMap() {
    for i := 0; i < cnt; i++ {
        for j := 0; j < cnt; j++ {
            intMapMap[i][j] = j
        }
    }
}

func printMemStats() {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    log.Printf("Alloc = %v TotalAlloc = %v  Just Freed = %v Sys = %v NumGC = %v\n",
        m.Alloc/1024, m.TotalAlloc/1024, ((m.TotalAlloc-m.Alloc)-lastTotalFreed)/1024, m.Sys/1024, m.NumGC)

    lastTotalFreed = m.TotalAlloc - m.Alloc
}

结果

2018/09/29 20:10:27 Alloc = 64 TotalAlloc = 64  Just Freed = 0 Sys = 1700 NumGC = 0
2018/09/29 20:10:27 Alloc = 41154 TotalAlloc = 41157  Just Freed = 3 Sys = 46026 NumGC = 5
2018/09/29 20:10:27 Alloc = 41241 TotalAlloc = 41293  Just Freed = 48 Sys = 47082 NumGC = 6
2018/09/29 20:10:27 1024
2018/09/29 20:10:27 0
2018/09/29 20:10:27 Alloc = 114 TotalAlloc = 41295  Just Freed = 41128 Sys = 47082 NumGC = 7
2018/09/29 20:10:27 Alloc = 74 TotalAlloc = 41296  Just Freed = 41 Sys = 47082 NumGC = 8

参考资料

如果这篇文章对你有帮助,请点个赞/喜欢,让我知道我的写作是有价值的,感谢。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序是怎样跑起来的

程序是怎样跑起来的

[日] 矢泽久雄 / 李逢俊 / 人民邮电出版社 / 2015-4 / 39.00元

本书从计算机的内部结构开始讲起,以图配文的形式详细讲解了二进制、内存、数据压缩、源文件和可执行文件、操作系统和应用程序的关系、汇编语言、硬件控制方法等内容,目的是让读者了解从用户双击程序图标到程序开始运行之间到底发生了什么。同时专设了“如果是你,你会怎样介绍?”专栏,以小学生、老奶奶为对象讲解程序的运行原理,颇为有趣。本书图文并茂,通俗易懂,非常适合计算机爱好者及相关从业人员阅读。一起来看看 《程序是怎样跑起来的》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具