Linux学习之路嵌入式 Linux C ARM 我用 Linux

LINUX存储相关知识串烧

2018-12-28  本文已影响1人  Leon_Geo

linux 内存是所有从事相关技术人员,需要深入了解的计算机资源管理方法论,合理的使用内存,有助于提升机器的性能和稳定性。本文主要从内存的原理和结构,到内存的算法优化,再到使用场景,去探寻内存管理的机制和奥秘。主要介绍了 linux 内存组织结构和页面布局,内存碎片产生原因和优化算法,linux 内核几种内存管理的方法,内存使用场景以及内存使用的那些坑

一 走进 linux 内存

1、内存是什么?

  1. 内存又称主存,是 CPU 能直接寻址的存储空间,由半导体器件制成,主要是DRAM构成。
  2. 内存的最核心特点是可随机存取,存取速率快。 计算机系统存储体系结构图

2、内存的作用

从微观来,CPU的运算需要空间存放中间数据。从宏观来看,系统的运行或进程的执行都需要一个存储空间去容纳它的数据,而这个空间就是内存。
1.暂时存放 cpu 的运算数据;
2.硬盘等外部存储器交换的数据;
3.保障 cpu 计算的稳定性和高性能;

计算机存储器 典型容量 存取时间
寄存器 <KB 1ns
一级cache <MB 5-10ns
二级cache 1-10MB 50ns
内存 0.1-100GB 100ns
硬盘 0.1-10TB 10ms
可移动存储介质 0.1-10TB 1-100ms

二 linux 内存空间

1、linux 内存地址空间

Linux内存管理全貌

2、内存地址——用户态&内核态

3、内存地址——MMU 地址转换

4、内存地址——分段机制

1. 段选择符

2. 分段实现

逻辑地址的段寄存器中提供了段描述符,然后从段描述符中得到段基址和段界限,然后加上逻辑地址的偏移量,就得到了线性地址。

5、内存地址——分页机制(32 位)

6、用户态地址空间

7、内核态地址空间

8、进程内存空间

三 Linux内存分配算法

1、内存碎片

1.基本原理

2.如何避免内存碎片

2、伙伴系统算法——组织结构

1. 概念

为内核提供了一种用于分配一组连续页而建立的一种高效的分配策略,并有效的解决了外碎片问题。分配的内存区是以页框(4KB)为基本单位的

2.外部碎片

外部碎片指的是还没有被分配出去,但又由于太小了而无法分配给其它申请内存空间的新进程的内存空间。

3.组织结构

把所有的空闲页分组为 11 个块链表,每个块链表分别包含大小为 1,2,4,8,16,32,64,128,256,512 和 1024 个连续页框的页块。最大可以申请 1024 个连续页,对应 4MB 大小的连续内存。 伙伴系统组织结构

3、伙伴系统算法——申请和回收

0.何为伙伴关系

大小相同的两块内存块,如果他们在物理上相连,则称为伙伴关系,否则为非伙伴关系。 伙伴关系

1.申请算法

申请 2^i 个页块存储空间

2.回收算法

释放 2^i 个页块存储空间

4、如何分配 4M 以上内存?

1.为何限制大块内存分配

2.内核中获取 4M 以上大内存的方法

5、伙伴系统——反碎片机制

1. 不可移动页

2. 可回收页

这些页不能移动,但可以删除。内核在回收页占据了太多的内存时或者内存短缺时进行页面回收###3. 可移动页

6、slab 算法——基本原理

1. 基本概念

2. 内部碎片

已经被分配出去的的内存空间大于请求所需的内存空间

3. 基本目标

7、slab 分配器的结构

8、slab 高速缓存

1. 普通高速缓存

2. 专用高速缓存

9、内核态内存池

1. 基本原理

2. 内核 API

10、用户态内存池

1. C++ 实例 用户态内存池

11、DMA 内存

1. 什么是 DMA

直接内存访问是一种硬件机制,它允许外围设备和主内存之间直接传输它们的 I/O 数据,而不需要系统处理器的参与

2. DMA 控制器的功能

3. DMA 信号

四、 内存使用场景

1、内存的使用场景

2、用户态内存分配函数

  1. 如果当前连续内存块足够 realloc 的话,只是将 p 所指向的空间扩大,并返回 p 的指针地址。这个时候 q 和 p 指向的地址是一样的
  2. 如果当前连续内存块不够长度,再找一个足够长的地方,分配一块新的内存,q,并将 p 指向的内容 copy 到 q,返回 q。并将 p 所指向的内存空间删除

4、malloc 申请内存

5、缺页异常

6、用户进程访问内存分析

7、共享内存

1. 原理

2. shm 接口

五、 内存使用那些坑

1. C 内存泄露

2、C 野指针

3、C 资源访问冲突

4、STL 迭代器失效

5、C++ 11 智能指针

性能:当你创建新的对象,然后创建一个shared_ptr,这种情况发生两个动态内存分配,一个是来自新对象本身,再进行第二次由shared_ptr构造函数创建的管理器对象;
当你使用make_shared,C++编译器的单一内存分配大到足以容纳两个管理对象和新对象。

(1)原理分析:

(2)数据结构:

boost::weak_ptr //它是boost提供的一个弱引用的智能指针,它的声明可以简化如下:

namespace boost {
template <typename T> class weak_ptr {
public:
template <typename Y>
weak_ptr(const shared_ptr<Y>&r);
weak_ptr(const weak_ptr&r);
~weak_ptr();
T*get() const; //1用于访问智能指针对象
bool expired() const; //2用于检测所管理的对象是否已经释放
shared_ptr<T> lock() const;3用于获取所管理对象的强引用指针
};
}

(3)使用方法:

  1. lock() 获取所管理的对象的强引用指针
  2. expired() 检测所管理的对象是否已经释放
  3. get() 访问智能指针对象

6、C++ 11 更小更快更安全

六、 如何查看内存

To free pagecache, use
echo 1 > /proc/sys/vm/drop_caches

To free dentries and inodes, use
echo 2 > /proc/sys/vm/drop_caches

To free pagecache, dentries and inodes, use
echo 3 >/proc/sys/vm/drop_caches

上一篇 下一篇

猜你喜欢

热点阅读