我不时会面对像零垃圾这样的概念或有效使用内存等。作为知名软件包httprouter的功能部分中的示例,您可以看到以下内容:
零垃圾:匹配和调度过程会产生零字节的垃圾。事实上,唯一的堆分配是通过构建路径参数的键值对的切片。如果请求路径不包含任何参数,则不需要单个堆分配。
与标准库的http.ServeMux相比,此软件包显示了非常好的基准测试结果:
BenchmarkHttpServeMux 5000 706222 ns/op 96 B/op 6 allocs/op
BenchmarkHttpRouter 100000 15010 ns/op 0 B/op 0 allocs/op
据我所知,第二个(从表中)没有堆内存分配和每次重复的零平均分配数。
问题:我想学习对内存管理的基本了解。当垃圾收集器分配 / deallocates内存时。基准数字意味着什么(表格的最后两列)以及人们如何知道堆分配的时间?
我在内存管理方面绝对是新手,因此很难理解“幕后”发生了什么。我读过的文章:
答案 0 :(得分:9)
垃圾收集器不分配内存:-),它只是解除分配。 Go的垃圾收集器正在不断发展,详细信息请查看设计文档https://docs.google.com/document/d/16Y4IsnNRCN43Mx0NZc5YXZLovrHvvLhK_h0KN8woTO4/preview?sle=true,并按照golang邮件列表的讨论进行操作。
基准测试输出中的最后两列非常简单:总共分配了多少字节,以及在基准代码的一次迭代中发生了多少分配。 (此分配由您的代码完成,而不是由垃圾收集器完成)。由于任何分配都是潜在的垃圾减少,这些数字可能是设计目标。
什么时候在堆上分配?每当Go编译器决定!编译器尝试在堆栈上进行分配,但有时它必须使用堆,尤其是当值从本地堆栈范围转义时。这种转义分析目前正在进行返工,因此要分析堆或堆栈分配的值是不容易的,特别是当它从编译器版本更改为版本时。
在基准测试显示过多的GC开销之前,我不会过于沉迷于避免分配。