6-1 内存布局

2019-09-29  本文已影响0人  荷码人生

在这一个章节中,主要讲述的内存布局的中的问题。我们知道了内存是分段的式的。系统将内存分成了这几个段:从下到上,从低地址到高地址分别是:保留区域、代码段(.text)、已初始化数据(.data)(全局变量以及静态变量)、未初始化数据(.bss)(全局变量以及静态变量)、堆区(heap)、栈区(stack)(定义的函数或者方法是在此处工作的)、内核区等。其中栈区是方法的运行区,是从高地址到低地址进行扩展,所以栈是向下增长或事向下扩展的、堆区是alloc的对象以及block copy后的对象,都是存放在这里的。堆是从低地址到高地址进行扩展,向上增长的。

具体如下:

内存布局.png

内存管理方案

内存管理方案,根据管理的对象不同可分为如下三种:

NONPOINTER_ISA(非指针型的isa)

arm64架构:

实际上它有64位bit位,

SideTable(散列表)

散列表在内存中使用SideTables()结构实现的。
Side Tables实际中是一个哈希表,我们可以通过一个指针来找到对应的引用计数表或者弱引用表,在哪一个具体的side table表中。Side Tables 包含有多个side table表。不通的系统,数目不同。

**Side Table的结构

包含有:

**为什么不是一个Side Table ,而是一个呢?(查找效率的原因)

假如说只有一张表,那就是说,我们在内存中的分配的所有对象的引用计数都在同一张表中。这是,如果我们要修改某个对象的引用计数值。由于不同对象在不同的线程中创建或分配,为了保证数据的访问安全,我们要对数据进行加锁处理。这个时候,就出现了访问效率的问题。使用分离锁可以很好的解决这个问题。

分离锁

所谓的分离锁,就是将内存对象的引用计数表,分成多个部分。比如说分成8个。就说对于在不同表中的对象可以并发访问,从而提高访问效率。如下图:

分离锁.png

怎样实现快速分流?

所谓的快速分流,就是我们通过对象的指针如何快速的定位到它在哪一张 sidetable表中。

Hash表

对象指针,通过Hash函数,计算出的value值(就是sideTables 的index索引)就是,该对象所在hash表的位置。

Hash查找
给定值是对象内存地址,目标值是数组(sideTables )下的索引。为什么使用hash查找?提高查找效率,避免了遍历的过程。由于存储和访问使用的是同一个Hash函数,所以我们可以通过Key,查找相对应地值,这样就避免了数组的遍历查找的过程。
如图所示:

屏幕快照 2019-09-07 下午6.41.26.png
数据结构(散列表)
  1. Spinlock_t 自旋锁
  1. 信号量:当它获取不到这个锁的时候,它会阻塞休眠,直到锁被释放后,来唤醒当前线程。
  2. RefcountMap引用计数表(Hash表)(Hash查找)
引用计数表 size_t 数据结构
weak_table_t 弱引用计数表(Hash 表)

weak_entry_t 结构体数组:存储的是弱引用指针
(__weak,__block)。

屏幕快照 2019-09-07 下午7.06.59.png
上一篇 下一篇

猜你喜欢

热点阅读