工大后院

 找回密码
 加入后院

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
楼主: jinry

关于堆内存管理?

[复制链接]
发表于 2008-8-7 23:56 | 显示全部楼层
所以free肯定是能够确定要释放多少内存的。同时,由于free的顺序不需要遵循分配的顺序,碎片肯定会产生,关键我们该怎么避免?
楼下继续。
回复

使用道具 举报

发表于 2008-8-8 13:12 | 显示全部楼层
再去MSDN啃了篇Managing Heap Memory in Win32的文章. 里面讲到几个方面:
1. 在WinNT中每个process有一个堆叫default heap , malloc函数使用的就是这个堆. 这个堆的大小在链接时指定, 一般默认为4KB committed , 1MB reserved . 它可以自动增长, 用户的工作地址空间有2GB . 默认堆的句柄可由GetProcessHeap得到..在EXE文件中也保存了堆栈大小的信息.
2. 关于内存碎片. 在使用 GlobalAlloc , LocalAlloc 时, 可以指定分配内存的类型. 里面有以下这么一段话:  It is surprising that the distinction between FIXED and MOVEABLE memory still exists in these functions. In Windows 3.1, MOVEABLE memory compacted the local and global heaps to reduce fragmentation and make more memory available to all applications. Yet the Windows NT virtual memory system does not rely on these techniques for efficient memory management and has little to gain by applications using them. In any case, they still exist and could actually be used in some circumstances.  里面似乎有提到紧凑内存, 但是在遥远的windows3.1时代了.  
3. 还有一个是提到引入虚拟内存后,windows自己管理物理内存页面的碎片? 这个不太懂,  很多概念我都忘记了, 所以没怎么明白   . 但意思就是我们无需担心内存碎片, windows自己会处理好.
4. 最后还有一句话: Heaps do at least one thing well—they allocate smaller chunks of memory rather quickly
回复

使用道具 举报

发表于 2008-8-8 13:14 | 显示全部楼层
不懂linux , 所以linux是怎样实现malloc的就不知道了.
回复

使用道具 举报

发表于 2008-8-8 17:11 | 显示全部楼层
如果自己实现malloc的话,我倒是曾经做过,就是移动数据段的下限。
回复

使用道具 举报

发表于 2008-8-8 17:22 | 显示全部楼层
linux下的。
回复

使用道具 举报

发表于 2008-8-8 17:25 | 显示全部楼层
抄一段,也没调过。大家看看。malloc 的。
* Take from the IBM development formum*/

/* Include the sbrk function */
#include <unistd.h>

int has_initialized = 0;
void *managed_memory_start;
void *last_valid_address;

void malloc_init()
{
/* grab the last valid address from the OS */  
last_valid_address = sbrk(0);     

/* we don't have any memory to manage yet, so
  *just set the beginning to be last_valid_address
  */  
managed_memory_start = last_valid_address;     

/* Okay, we're initialized and ready to go */
  has_initialized = 1;   
}

struct mem_control_block {
int is_available;
int size;
};

void free(void *firstbyte) {
struct mem_control_block *mcb;  

/* Backup from the given pointer to find the
  * mem_control_block
  */
mcb = firstbyte - sizeof(struct mem_control_block);   
/* Mark the block as being available */
mcb->is_available = 1;   
/* That's It!  We're done. */
return;   
}  

void *malloc(long numbytes) {
/* Holds where we are looking in memory */
void *current_location;

/* This is the same as current_location, but cast to a
  * memory_control_block
  */
struct mem_control_block *current_location_mcb;  

/* This is the memory location we will return.  It will
  * be set to 0 until we find something suitable
  */  
void *memory_location;  

/* Initialize if we haven't already done so */
if(! has_initialized)  {
  malloc_init();
}

/* The memory we search for has to include the memory
  * control block, but the user of malloc doesn't need
  * to know this, so we'll just add it in for them.
  */
numbytes = numbytes + sizeof(struct mem_control_block);  

/* Set memory_location to 0 until we find a suitable
  * location
  */
memory_location = 0;  

/* Begin searching at the start of managed memory */
current_location = managed_memory_start;  

/* Keep going until we have searched all allocated space */
while(current_location != last_valid_address)  
{
  /* current_location and current_location_mcb point
   * to the same address.  However, current_location_mcb
   * is of the correct type so we can use it as a struct.
   * current_location is a void pointer so we can use it
   * to calculate addresses.
   */
  current_location_mcb =
   (struct mem_control_block *)current_location;

  if(current_location_mcb->is_available)
  {
   if(current_location_mcb->size >= numbytes)
   {
    /* Woohoo!  We've found an open,
     * appropriately-size location.  
     */

    /* It is no longer available */
    current_location_mcb->is_available = 0;

    /* We own it */
    memory_location = current_location;

    /* Leave the loop */
    break;
   }
  }

  /* If we made it here, it's because the Current memory
   * block not suitable, move to the next one
   */
  current_location = current_location +
   current_location_mcb->size;
}

/* If we still don't have a valid location, we'll
  * have to ask the operating system for more memory
  */
if(! memory_location)
{
  /* Move the program break numbytes further */
  sbrk(numbytes);

  /* The new memory will be where the last valid
   * address left off
   */
  memory_location = last_valid_address;

  /* We'll move the last valid address forward
   * numbytes
   */
  last_valid_address = last_valid_address + numbytes;

  /* We need to initialize the mem_control_block */
  current_location_mcb = memory_location;
  current_location_mcb->is_available = 0;
  current_location_mcb->size = numbytes;
}

/* Now, no matter what (well, except for error conditions),
  * memory_location has the address of the memory, including
  * the mem_control_block
  */

/* Move the pointer past the mem_control_block */
memory_location = memory_location + sizeof(struct mem_control_block);

/* Return the pointer */
return memory_location;
}
回复

使用道具 举报

发表于 2008-8-9 11:34 | 显示全部楼层
free的时候不是要传进一个指针吗?
通过那个指针可以获得内存数
具体实现与编译器有关
有些就直接把内存数存在指针所指向的地址前面两个字节
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入后院

本版积分规则

QQ|Archiver|手机版|小黑屋|广告业务Q|工大后院 ( 粤ICP备10013660号 )

GMT+8, 2025-5-14 00:34

Powered by Discuz! X3.5

Copyright © 2001-2024 Tencent Cloud.

快速回复 返回顶部 返回列表