C++ new / new[],它是如何分配内存的?
我现在想知道这些指令如何分配内存。
例如,如果我得到代码怎么办:
x = new int[5];
y = new int[5];
如果这些代码被分配,那么它在 RAM 中的实际情况如何? 是否为每个变量保留整个块,或者块(内存页或如何称呼它 - 32 位上的 4KB 大小)为 2 个变量共享?
我在任何手册中都找不到我的问题的答案。感谢您的所有回复。
我在维基百科上找到: 页面内部碎片 进程很少需要使用精确数量的页面。因此,最后一页可能只是部分满,浪费了一些内存。较大的页面大小显然会增加这种方式浪费内存的可能性,因为更多可能未使用的内存部分会加载到主内存中。较小的页面大小可确保更接近分配中所需的实际内存量。 例如,假设页面大小为 1024KB。如果一个进程分配1025KB,则必须使用两个页面,从而导致1023KB的未使用空间(其中一个页面完全消耗1024KB,而另一页面仅消耗1KB)。
这就是我问题的答案。不管怎样谢谢大家。
I would like to now how those instructions are allocating memory.
For example what if I got code:
x = new int[5];
y = new int[5];
If those are allocated how it actually looks like in RAM?
Is whole block reserved for each of the variables or block(memory page or how-you-call-it - 4KB of size on 32bit) is shared for 2 variables?
I couldn't find answer for my question in any manual. Thanks for all replies.
I found on wikipedia:
Internal fragmentation of pages
Rarely do processes require the use of an exact number of pages. As a result, the last page will likely only be partially full, wasting some amount of memory. Larger page sizes clearly increase the potential for wasted memory this way, as more potentially unused portions of memory are loaded into main memory. Smaller page sizes ensure a closer match to the actual amount of memory required in an allocation.
As an example, assume the page size is 1024KB. If a process allocates 1025KB, two pages must be used, resulting in 1023KB of unused space (where one page fully consumes 1024KB and the other only 1KB).
And that was answer for my question. Anyway thanks guys.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
典型的分配器实现将首先调用操作系统来获取巨大的内存块,然后为了满足您的请求,它会给您一块内存,这称为子分配。如果内存不足,它将从操作系统获取更多内存。
分配器必须跟踪它从操作系统获得的所有大块以及它分发给客户端的所有小块。它还必须接受客户端返回的块。
典型的子分配算法保留每个大小的返回块的列表,称为空闲列表,并且始终尝试满足来自空闲列表的请求,仅在空闲列表为空时才转到主块。这种特殊的实现技术对于普通程序来说非常快速且非常有效,但如果请求大小到处都是(这对于大多数程序来说并不常见),它会产生糟糕的碎片属性。
像 GNU 的 malloc 实现这样的现代分配器很复杂,但已经建立了数十年的经验,并且应该被认为非常好,以至于很少需要编写自己的专用子分配器。
A typical allocator implementation will first call the operating system to get huge block of memory, and then to satisfy your request it will give you a piece of that memory, this is known as suballocation. If it runs out of memory, it will get more from the operating system.
The allocator must keep track of both all the big blocks it got from the operating system and also all the small blocks it handed out to its clients. It also must accept blocks back from clients.
A typical suballocation algorithm keeps a list of returned blocks of each size called a freelist and always tries to satisfy a request from the freelist, only going to the main block if the freelist is empty. This particular implementation technique is extremely fast and quite efficient for average programs, though it has woeful fragmentation properties if request sizes are all over the place (which is not usual for most programs).
Modern allocators like GNU's malloc implementation are complex, but have been built with many decades of experience and should be considered so good that it is very rare to need to write your own specialised suballocator.
您在手册中没有找到它,因为标准没有指定它。也就是说,大多数时候 x 和 y 将并排(继续并
cout<< hex <<
它们的地址)。但标准中没有任何内容强制这样做,因此您不能依赖它。
You didn't find it in the manual because it's not specified by the standard. That is, most of the time x and y will be side by side (go ahead and
cout<< hex <<
their addresses).But nothing in the standard forces this so you can't rely on it.
每个进程都有不同的关联段,这些段被划分在进程地址空间中:
1) 文本段:: 你的代码放置的地方
2) 堆栈段::进程堆栈
3) 数据段:: 这是“new”保留内存的地方。除此之外,它还存储已初始化和未初始化的静态数据(bss 等)。
因此,每当您调用一个新函数(我猜它在内部使用 malloc ,但新类使得处理内存更加安全)时,它都会在数据段中分配指定数量的字节。
当然,您在运行程序时打印的地址是虚拟的,需要转换为物理地址..但这不是我们头疼的问题,操作系统内存管理单元为我们做到了这一点。
Each process has different segments associated which are divided among the process address space :
1) The text segment :: Where your code is placed
2) Stack Segment :: Process stack
3) Data Segment :: This is where memory by "new" is reserved. Besides that it also store initialized and uninitialized static data (bss etc).
So , whenever you call a new function (which i guess uses malloc internally , but the new class makes it much safer to handle memory) it allocates the specified number of bytes in the data segment.
Ofcourse the address you print while running the program is virtual and needs to be translated to physical address..but that is not our headache and the OS Memory management unit does that for us.