常见内存问题

内存泄漏

  • 形象描述:内存像气球漏气一样,漏掉部分(不能使用),只剩下整体的部分(能够被使用)。

理解

  • 栈内存,.data, .bss 等内存段中的内存申请和释放都是由系统处理的,按我当前的理解是不会造成内存泄漏,只有堆内存,是由程序员管理的,出现野指针(指针指向的内存是堆内存,内存申请了但是没有释放,内存地址也被丢失)等会导致内存泄漏。

内存溢出

  • 形象描述:内存像容器,被加入超过容器容量大小的水(数据),由于没有边界限制,部分水覆盖了其它空间(部分数据覆盖了其它数据的内存空间)。

理解

  • 内存溢出和具体的内存段无关,栈内存,堆内存等都可能溢出。
  • 但是人们常说栈内存溢出,而不说堆内存溢出的原因如下:
  1. 栈内存数据是紧挨着的,数据一旦溢出,非常容易造成影响,不像堆内存是散布的,即使溢出也可能无影响。
  2. 进程由线程组成,每个线程的栈大小是非常有限的,不像堆内存地址范围是非常大的,栈大小可以通过命令ulimit查看和设置,如下:
xxx@chejiser:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 515581
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 515581
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
xxx@chejiser:~$ ulimit -s
8192
  • 栈溢出的原因:由于C/C++语言对内存边界不做检查,在函数递归或栈内存使用不当时,可能出现栈内存使用超出栈大小的情况,或者栈上分配的内存小于使用的内存,可能导致意想不到的现象,如下:
* 栈内存使用不当,示例代码
#include 

void input(){
	char a[10];
	
	gets(a); //使用的内存可能大于分配的内存
}

int main(){
    char a[1024*1024*10] = {0}; //栈内存超限
    int b = 1;
	
    printf("b: %d\n", b);
    return 0;
}

* 运行结果
xxx@chejiser:~$ ./test
Segmentation fault (core dumped)
  • 栈内存使用,数据压栈和出栈,感觉是弹性的,为何会超限?
  1. 栈内存并不是所有操作都是按栈的方式操作的,只是编译时变量的创建是按栈的方式分配内存地址,程序运行时,变量的操作和堆等其它数据段一样,都是按照内存地址操作,如下:
* 代码 "stack.c"

int main(){
 int a = 10;
 int b = 12;

 return 0;
}

* 相关汇编代码
	movl	$10, -8(%rbp)
	movl	$12, -4(%rbp)

附录

  • 程序内存分段:
  • https://blog.csdn.net/qazw9600/article/details/106148478

你可能感兴趣的:(#,Linux,内核知识)