垃圾回收(Garbage Collection)也被称为自动内存管理技术,在现代编程语言中使用得相当广泛,常见的 Java、Go、C# 均在语言的 runtime 中集成了相应的实现。
对象创建,内存分配
观察对象分配时,主要有三个参与者,Application,allocator,grabage collector ,接下来看一下这三者如何工作的
编辑切换为居中
添加图片注释,不超过 140 字(可选)
Application指的是我们的应用,我们将堆上的对象看作一个图,应用代码分配变量时就是在不停地修改这张堆对象图里的指向关系。
下图可以帮我们理解分配对象时堆上的操作
编辑
添加图片注释,不超过 140 字(可选)
allocator 就很好理解了,指的是内存分配器,应用需要内存的时候都要向 allocator 申请。
allocator 要维护好内存分配的数据结构,在多线程场景下工作的内存分配器还需要考虑高并发场景下锁的影响,并针对性地进行设计以降低锁冲突。
collector 是垃圾回收器。
死掉的堆对象、不用的堆内存都要由 collector 回收,最终归还给操作系统。当 GC 扫描流程开始执行时,collector 需要扫描内存中存活的堆对象,扫描完成后,未被扫描到的对象就是无法访问的堆上垃圾,需要将其占用内存回收掉。
内存分配器
内存分配器在应用和操作系统之间工作,当应用需要分配内容是,应用将一个结构或者一个分片申请内存分配,内存分配器判断当前已经分配的内存是否足够,足够时将当前内存start和offset返回给应用程序,不足够时向应用程序申请一块足够大小的内存。内存分配器的存在:1.隔离了应用程序多次向操作系统申请内存。2.内存碎片化管理。
栈内存由操作系统分配,堆内存由人为手动分配和释放,下表是总结的栈和堆的区别
栈 | 堆 | |
---|---|---|
速度 | 快 | 慢 |
空间管理 | 高效,不会产生碎片 | 会产生内存碎片 |
访问权限 | 只能局部变量 | 可以访问全局变量 |
空间大小限制 | 操作系统限制 | 没有特定的限制 |
内存分配 | 连续 | 随机分配 |
分配和释放 | 编译器指令自动管理 | 手动管理 |
开销 | 低 | 高 |
主要问题 | 空间小 | 内存碎片 |
灵活性 | 固定大小 | 可以resize |
堆内存手动管理,创建一个堆内存时,也需要将堆内对象