cleanerxiaoqiang 2020-05-08
1.内存池:向系统申请大块内存,然后进行管理和分配(管理内存分配)。
2.垃圾回收:当分配的内存使用完之后,不直接归还给系统,而是归还给内存池,方便进行下一次复用。至于垃圾回收选择标记回收,还是分代回收算法应该符合语言设计初衷。
3.大小切分:使用单独的数组或者链表,把需要申请的内存大小向上取整,直接从这个数组或链表拿出对应的大小内存块,方便分配内存。大的对象以页申请内存,小的对象以块来申请,避免内存碎片,提高内存使用率。
4.多线程管理:每个线程应该有自己的内存块,这样避免同时访问共享区的时候加锁,提升语言的并发性,线程之间通信使用消息队列的形式,一定不要使用共享内存的方式。提供全局性的分配链,如果线程内存不够用了,可向分配链申请内存。
Go语言自带垃圾回收功能,大多数情况下是不需要用户自己管理内存的;tcmalloc(thread-caching mallo)是google推出的一种内存分配器。
具体策略:全局缓存堆和进程的私有缓存。golang语言中MHeap就是全局缓存堆,MCache作为线程私有缓存。
golang内存分配器主要包含三个数据结构:MHeap,MCentral、MCache。
1、MHeap:分配堆,主要是负责向系统申请大块的内存,为下层MCentral和MCache提供内存服务。它管理的基本单位是MSpan(若干连续内存页的数据结构)。MSpan是一个双端链表的形式,里面存储了它的一些位置信息。通过一个基地址+(页号*页大小),就可以定位到这个MSpan的实际内存空间。
2、MCache:运行时分配池,不针对全局,而是每个线程都有自己的局部内存缓存MCache,他是实现goroutine高并发的重要因素,因为分配小对象可直接从MCache中分配,不用加锁,提升了并发效率。
3、MCentral:作为MHeap和MCache的承上启下的连接。承上,从MHeap申请MSpan;启下,将MSpan划分为各种尺寸的对象提供给MCache使用。
给对象 object 分配内存的主要流程:
总结:
?python中万物皆对象,python的存储问题是对象的存储问题,并且对于每个对象,python会分配一块内存空间去存储它
Python的内存管理机制:引入计数、垃圾回收、内存池机制
Python垃圾回收主要以引用计数为主,标记?清除和分代清除为辅的机制,其中标记?清除和分代回收主要是为了处理循环引用的难题
一、变量与对象
二、引用计数
三、垃圾回收
四、内存池机制
Python中有分为大内存和小内存:(256K为界限分大小内存)
Python的内存管理是由私有heap空间管理的.所有的Python对象和数据结构都在一个私有heap中.程序员没有访问该heap的权限,只有解释器才能对它进行操作.为Python的heap空间分配内存是由Python的内存管理模块进行的,其核心API会提供一些访问该模块的方法供程序员使用.Python有自带的垃圾回收系统,它回收并释放没有被使用的内存,让它们能够被其他程序使用;
内存管理系统可以分为两部分,分别是内核空间内存管理和用户空间内存管理:
————内存管理子系统的职责是:进程请求内存时分配可用内存,进程释放内存后回收内存,以及跟踪系统内存使用情况。现代操作系统要求能够使多个程序共享系统资源,同时要求内存限制对于开发者是透明的。在这种情况下,虚拟内存应运而生。虚拟内存可以使得进程可以访问比实际内存大得多的空间,并且使得多个程序共享内存显得更加有效。
————当程序从内存中取得数据的时候,需要使用地址指出需要访问的内存位置(注意:这个地址是虚拟地址,他们组成的进程的虚拟地址空间)。每个进程都有自己的虚拟地址空间,这样做的好处是可以防止非法读取或覆盖其他进程的数据(虚拟地址允许进程使用超过物理内存的内存空间,因此操作系统可以给每个进程提供独立的虚拟线性地址空间。)
<页>
a:作为内存管理的基本单元,页的许多状态需要被记录下来(比如,内核需要知道什么时候可以被回收),因此内核为内核中的每个页都准备了页描述符struct page{}.系统在初始化时根据物理内存的大小建立起一个page结构数组mem_map,作为物理页面的“仓库”
由此可见,slab时间上由许多缓存组成。缓存分为"专用"和"通用"。专用缓存保存特定对象的内存区,比如各种描述符,比如进程描述符"struct task_structs".
<用户空间/进程内存管理>
-------以上讨论了内核如何管理自己的内存空间,接下来讨论用户空间如何让管理自己的内存空间。用户进程创建后需要分配一个虚拟地址空间,并且可用通过增加或删除地址间隔得以扩大或缩小。(地址间隔(一段地址空间):是一种内存单元,也被称作内存范围或内存区,把进程地址空间划分为不同的区域是有用的,不同的区域具有不同的保护方案和访问属性,比如".text"".data"".bss""栈""栈")。