课程笔记:c++内存管理
type
status
date
slug
summary
tags
category
icon
password
只关注虚拟内存,包括用户态的内存管理,不包括内核态的内存管理和物理内存。涉及一些cpu cache。以及一些示例参考。
课程大纲:
- c++以外的内存管理(操作系统,c语言层次的内存管理)
- c++的内存管理机制的发展
- 如何使用c++的内存管理机制?(分为两种)
- global allocator 全局分配器
- local allocator 局部分配器
- 通用malloc的实现
- 不用动c++的global allocator (new / delete operator)
- 直接用更先进的malloc实现来替换掉默认的实现
- 局部分配器 local allocator(std::pmr)的用途与效果
1. c++以外的内存管理
操作系统的内存管理
linux内存管理,在/proc/{pid}/maps文件中,包含了该进程的虚拟内存的状态,如下所示:
其中包括经典的【heap】堆和【stack】栈,下图是经典的32 位机器上进程虚拟内存空间分布图
从操作系统角度来看,linux提供了两个系统调用来操作虚拟内存
- sbrk()/brk() 可以用来增加/减少heap,手册中说明sbrk/brk可以改变program break,这里可以将program break理解为heap生长的方向的尾部,即改变它,就是改变heap的大小;https://man7.org/linux/man-pages/man2/brk.2.html
- mmap 可以用来创建匿名内存段MAP_ANONYMOUS,默认是大块内存才使用mmap;
但是因为系统调用的调用成本比较高,需要切换到内核态,所以一般系统调用都是用来一次性申请一大块内存,不会用来申请小块内存。
c的内存管理
- mallloc和free:是基于系统调用sbrk或mmap实现的,分配的内存位于[heap] 堆 或者 匿名mmap
- alloca:用来分配栈上的内存[stack],是一个速度很快的函数,但是要注意分配的内存过大,可能会导致栈溢出、程序崩溃
- 库函数
malloc实际上是一种库函数实现,常规使用的是glibc默认的ptmalloc,但是其被认为是一种比较慢的实现,于是各家公司推出自己的malloc,比如google的tcmalloc,Facebook的jemalloc,microsoft的minalloc。
上述都可以去替换malloc,方法如下
- linux平台使用LD_PRELOAD
2. c++的内存管理
new/delete expression
c++是面向对象的语言,有构造、析构函数,不建议直接使用malloc/free,建议使用new/delete expression。
- new expression:编译器会先调用new operator,再调用构造函数;
- delete expression:编译器会先调用析构函数,再调用delete operator;
- global new/delete operator:可以被重载,对malloc/free的包装;
- class new/delete operator: 优先调用class new/delete operator,如果class没有定义new/delete operator,才会调用global new/delete operator;
- Twikoo
- Giscus
- Utterance
Last update: 2023-07-02
type
status
date
slug
summary
tags
category
icon
password
welcome to my world!