references:
一个C++源文件从文本到可执行文件经历的过程
C++源文件从文本到可执行文件经历的过程
gcc程序编译的静态链接和动态链接
保留中间过程文件:a.i, a.s, a.o, a.out
g++ a.cpp -save-temps
?
对源代码文件中文件包含关系(头文件)、预编译语句(宏定义)进行分析和替换,成预编译文件。
等等
g++ -E a.cpp -o a.i
将经过预处理后的预编译文件转换成特定汇编代码,生成汇编文件。
g++ a.cpp -S
将编译阶段生成的汇编文件转化成机器码,生成可重定位目标文件。
g++ -c a.s -o a.o
将多个目标文件及所需要的库连接成最终的可执行文件。链接分为静态链接和动态链接。
动态链接:可执行文件只是包含了文件名,运行时才把他们链接到一起。优点是可执行文件体积小,更新方便;缺点是运行速度慢。
g++ a.o -o a //动态链接
g++ a.o -static -o a //静态链接
如果a.h中定义了b.h中声明的变量并且a.h没有引用b.h,那么引用a.h前要先引用b.h。
当然这是显然的。
预处理阶段查找头文件的路径不一样。
references:
nowcoder
malloc底层原理实现
malloc采用内存池,申请大块内存作为堆区,将堆区分成多个内存块进行管理。用一个(隐式)空闲链表将空闲块连在一起,每个空闲块存了一个连续的、未分配的地址。
在内存分配时,malloc会通过空闲链表遍历查找符合大小的块,然后把空闲块分成两个块,一个变成分配块,一个变成新的空闲块;在内存合并时,malloc用边界标记法,根据前后块是否分配进行合并。(减少内存碎片)
references:
内存分配系统调用:brk和mmap
请问malloc的分配为什么是小内存用brk,大内存用mmap,各自有什么好处?
Linux中brk()系统调用,sbrk(),mmap(),malloc(),calloc()的异同
实现虚拟内存到内存的映射
申请内存小于128K的时候,使用brk系统在堆区分配;大于128K的时候,使用mmap在映射区分配。
原因:
brk指针只有一个,分配内存时是把进程堆的最高地址往高地址上推,只有高地址释放后才能释放低地址内存,如果大内存用brk分配会产生内存碎片。
mmap分配内存可以单独释放,但是分配小内存使得缺页中断次数增加,性能下降。
1、堆内存泄漏:new/malloc之后没有deete/free,申请的内存没有释放。
2、系统资源泄漏:主要指程序使用系统分配的资源比如 Bitmap,handle ,SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定。
使用Linux环境下的内存泄漏检查工具Valgrind。
访问非法内存地址(数组访问越界等),访问只读的内存地址(字符串常量等),栈溢出。
采用两级配置器结构:
申请空间大于128byte,使用一级配置器。包含malloc()、remalloc()、free()等C函数执行实际的内存配置,释放,重新配置等操作。
分配小于128字节内存时,以内存池进行管理。
内存池每次配置一块内存,并维护对应的16个空闲链表(free-list),每个节点分别管理大小为为8,16,24,32,……,120,128的数据块。
向二级配置器申请时,将申请内存扩大到8的倍数,去找空闲链表对应的位置,然后找子链表。子链表不为空,就分配链表头表示的内存,表头指向下一个节点;为空则向内存池申请(一般一次20块),分配到子链表中,再把链表头分配出去。
作用:在STL的第二级配置器中多了一些机制,避免太多小区块造成的内存碎片,小区块造成的不仅仅是内存碎片,同时还有一些额外的负担。区块越小,额外的负担所占的比重越大。
原文:https://www.cnblogs.com/KirinSB/p/12521159.html