课程笔记:c++内存管理

type
status
date
slug
summary
tags
category
icon
password
只关注虚拟内存,包括用户态的内存管理,不包括内核态的内存管理和物理内存。涉及一些cpu cache。以及一些示例参考。

课程大纲:

  1. c++以外的内存管理(操作系统,c语言层次的内存管理)
  1. c++的内存管理机制的发展
  1. 如何使用c++的内存管理机制?(分为两种)
    1. global allocator 全局分配器
    2. local allocator 局部分配器
  1. 通用malloc的实现
    1. 不用动c++的global allocator (new / delete operator)
      1. 直接用更先进的malloc实现来替换掉默认的实现
  1. 局部分配器 local allocator(std::pmr)的用途与效果

1. c++以外的内存管理

操作系统的内存管理

linux内存管理,在/proc/{pid}/maps文件中,包含了该进程的虚拟内存的状态,如下所示:
其中包括经典的【heap】堆和【stack】栈,下图是经典的32 位机器上进程虚拟内存空间分布图
notion image
从操作系统角度来看,linux提供了两个系统调用来操作虚拟内存
  1. sbrk()/brk() 可以用来增加/减少heap,手册中说明sbrk/brk可以改变program break,这里可以将program break理解为heap生长的方向的尾部,即改变它,就是改变heap的大小;https://man7.org/linux/man-pages/man2/brk.2.html
  1. mmap 可以用来创建匿名内存段MAP_ANONYMOUS,默认是大块内存才使用mmap;
但是因为系统调用的调用成本比较高,需要切换到内核态,所以一般系统调用都是用来一次性申请一大块内存,不会用来申请小块内存。

c的内存管理

notion image
  1. mallloc和free:是基于系统调用sbrk或mmap实现的,分配的内存位于[heap] 堆 或者 匿名mmap
  1. alloca:用来分配栈上的内存[stack],是一个速度很快的函数,但是要注意分配的内存过大,可能会导致栈溢出、程序崩溃
  1. 库函数
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;
课程笔记:c++模版元编程基础基于可微渲染的智能资产辅助生产系统
  • Twikoo
  • Giscus
  • Utterance