最近在看go的一些底层的东西…对于go的gc稍微有一点感触。。所以想通过写文章的形式来梳理以下我对gc的一些理解。
这篇文章主要是概述一些内存管理的东西。然后可能会涉及到Garbage collection (GC)的一些知识。。过去几年的时间。go的内存管理发生了些许变化。不过应该问题不大,这时一篇比较概念性的文章。文章里面会涉及到go语言的调度器(scheduler)和 逃逸分析(escape analysis)的相关知识。当然也只是提及而已。行废话就到此为止.以下简称Garbage collection = GC
Garbage collection (GC) 是什么
可以去查阅相关的文档。也被叫做自动内存管理,是一种动态分配内存和自动回收技术。这个技术自从上世纪五十年代的时候开始运用,其目的是为了防止内存泄漏和内存崩溃,动态的分配和管理内存可以达到减轻程序员的负担从而提高生产力
手动内存管理&&自动内存管理
手动内存管理
在像C这样的语言中,程序员将调用malloc或calloc等函数来将对象写入内存,这些函数返回指向堆内存中该对象位置的指针。当不再需要这个对象时,程序员调用free函数再次使用这个内存块。这种内存管理方法称为explicit deallocation,毫无疑问这是非常强大。它使程序员能够更好地控制正在使用的内存。然而,在低内存的情况下,这个可能会造成两种情况的程序错误
-
过早调用free将会创建一个悬空指针( dangling pointer.)这个悬空指针指的是它不在指向有效的内存地址,这个是不可取的,因为程序希望一个已定义的值的地址被指针所指向(或者说程序希望定义的值位于指针处),当你稍微晚一点访问这个指针时,你无法保证其存在什么值。它可能什么都没有,也可能存在的值没什么意义
-
完全无法释放内存。如果程序员忘记释放一个对象,那么随着内存被越来越多的对象填满,他们可能会面临内存泄漏。如果内存不足,这可能导致程序减速或崩溃。当必须显式管理内存时,无法预测的错误可能会引入程序。
自动内存管理
为什么类似go一样的语言要使用自动内存管理,或者更加简单的,自动内存管理比起手动内存管理的优势在于哪里
- 增加了安全性。
- 写更少的代码
- 自动检查数组边界
…
GC对于程序本身就是一个性能的开销,但是它耗费的资源并没有你想象得那么多,这个开销权衡了程序员能够更加专注在自己得业务上,从而不用担心程序的内存管理,就像是上面所列举的优点。
堆和栈
一个正在运行的程序会把它的对象存储到两个本地的内存位置,那就是堆和栈。Garbage collection的运行是在堆上面运行的,而不是栈。
- 栈用于静态内存分配,与数据结构一样,是一种后进先出的数据结构,当我们从一个函数调用另外一个函数的时候 ,在内部会推送一个新的栈帧(stack frame)进入栈,我们可以在维基百科看到相关的解释这个包含函数的调用参数,当我们调用返回的时候,这个栈帧将会从栈中弹出,你可能会想起你在写代码的时候你的idea。在调试代码的时候就是用栈和堆的跟踪来帮助你去调试你的代码,

- 堆用于动态内存分配。栈只能在顶部分配和释放内存,堆可以在任何堆所在的位置进行内存的释放和分配,这意味着堆比栈更灵活。指针、数组和大数据结构通常存储在堆中。
存储在堆上的数据必须形成一个足够大的连续块,以便用单个内存块满足请求。此属性增加了堆的复杂性。首先,执行分配操作的代码必须扫描堆,直到找到足够大的连续内存块来满足请求。第二,当内存返回到栈时,相邻的释放块必须合并,以更好地适应将来对大内存块的请求。这种增加的复杂性意味着使用堆管理内存比使用堆栈慢。
堆内存分配方案不提供自动取消分配。为了有效地使用内存。当程序运行时,除非清理堆,否则堆将随着对象的添加而继续增长。

堆和栈比较
-
堆可以存储比栈更多的数据。
-
堆比栈慢,因为查找数据的过程更复杂。
-
堆存储具有动态大小的数据;栈以静态大小存储数据。
-
堆在应用程序的线程之间共享。

本文介绍了Go语言的垃圾收集(GC)原理,包括手动与自动内存管理、堆栈内存的区别、Go的内存模型以及GC的过程。通过理解GC,可以更好地优化代码,减少内存开销,提高程序性能。同时,文章探讨了如何通过调整结构体字段布局来减少内存浪费。
最低0.47元/天 解锁文章
398

被折叠的 条评论
为什么被折叠?



