ioe*_*ric 2 c c++ memory operating-system
我正在对堆地址增长做一些实验,并发生了一些有趣的事情.(OS:CentOS,)
但我不明白,为什么会这样?谢谢!
这是我先做的事情:
double *ptr[1000];
for (int i=0;i<1000;i++){
ptr[i] = new double[**10000**];
cout << ptr[i] << endl;
}
Run Code Online (Sandbox Code Playgroud)
输出是递增的(对于最后几行):
....
....
0x2481be0
0x2495470
0x24a8d00
0x24bc590
0x24cfe20
0x24e36b0
0x24f6f40
0x250a7d0
0x251e060
Run Code Online (Sandbox Code Playgroud)
然后我将10000改为20000:
double *ptr[1000];
for (int i=0;i<1000;i++){
ptr[i] = new double[**20000**];
cout << ptr[i] << endl;
}
Run Code Online (Sandbox Code Playgroud)
地址变得更像堆栈空间的地址(和递减):
....
....
0x7f69c4d8a010
0x7f69c4d62010
0x7f69c4d3a010
0x7f69c4d12010
0x7f69c4cea010
0x7f69c4cc2010
0x7f69c4c9a010
0x7f69c4c72010
0x7f69c4c4a010
0x7f69c4c22010
0x7f69c4bfa010
0x7f69c4bd2010
0x7f69c4baa010
0x7f69c4b82010
Run Code Online (Sandbox Code Playgroud)
不同的环境/实现使用不同的策略分配内存,因此没有一个正确的规则.但是,常见的模式是对小对象与大对象使用不同的分配策略.
通常,运行时将为不同大小的对象提供多个堆,这些对象针对不同的使用模式进行了优化.例如,小对象往往经常被分配并快速删除,而大对象往往很少创建并且寿命很长.
如果你为一切使用单个堆,那么一些小对象将在你的整个内存空间中迅速填充,留下许多中等大小的块可用,但较大的对象需要很少或不需要大块.这被称为内存碎片,即使名义上您的应用程序有大量可用内存,也可能导致您的分配失败.
使用不同堆的另一个原因是对不同的对象大小使用不同的使用跟踪方法.例如,实现可能会从操作系统请求大型对象的新内存块,对于小型对象,请使用一些较小的OS内存块和C运行时堆管理器处理的子分配.对于较大的对象非常有效的内存使用跟踪机制对于较小的对象来说可能非常昂贵,因为用于跟踪使用的内存成为每个对象使用的实际内存的重要部分.
在您的情况下,我的猜测是运行时在内存空间的开头分配小对象,从下到上分配较大的对象,从上到下分配较大的对象,以避免碎片.