返回

怎样应用异常实现懒分配?

见解分享

XV6学习 (7) Lab lazy: Lazy allocation

在了解懒分配之前,需要先了解内存是如何分配的。在计算机中,内存是一块连续的地址空间,每个地址对应一个字节的数据。当进程运行时,它需要使用内存来存储数据和代码。内存的分配是由操作系统负责的。操作系统会将内存划分为页面,每个页面的大小通常为4KB。当进程需要分配内存时,操作系统会从空闲页面中选择一个页面分配给进程。

懒惰分配 是一种内存管理策略,它只在需要时才分配内存。这种策略可以节省内存,因为只有实际使用的内存才会被分配。懒惰分配通常是通过使用页错误来实现的。当进程访问未分配的内存页面时,操作系统会引发页错误。然后,操作系统可以分配该页面并将其映射到进程的地址空间。这种方法只分配实际使用的内存页面,从而节省了内存。

懒分配的优点:

  • 节省内存 。只分配实际使用的内存,可以节省内存。
  • 提高性能 。因为只分配实际使用的内存,所以可以减少页面错误的数量,从而提高性能。
  • 简化内存管理 。懒惰分配可以简化内存管理,因为不需要预先分配所有内存。

懒分配的缺点:

  • 延迟访问 。当进程访问未分配的内存页面时,操作系统需要先分配该页面,然后才能访问该页面。这可能会导致延迟。
  • 增加复杂性 。懒惰分配增加了内存管理的复杂性,因为需要处理页错误。

懒惰分配的实现

懒惰分配通常是通过使用页错误来实现的。当进程访问未分配的内存页面时,操作系统会引发页错误。然后,操作系统可以分配该页面并将其映射到进程的地址空间。这种方法只分配实际使用的内存页面,从而节省了内存。

在XV6中,懒惰分配是通过sbrk系统调用来实现的。sbrk系统调用可以用来在堆上分配内存。当进程调用sbrk系统调用时,操作系统会分配一个新的内存页面并将其映射到进程的地址空间。如果分配成功,sbrk系统调用会返回新分配的内存页面的地址。如果分配失败,sbrk系统调用会返回-1。

lazy lab实验是要利用缺页异常来实现懒分配。用户态程序通过sbrk系统调用来在堆上分配内存,而sbrk则会通过kalloc函数来申请内存页面,之后将页面映射到页表当中。当申请小的空间时,上述过程是没有问题的。但是如果当进程试图申请一个大的空间时,可能会出现问题。原因在于,操作系统一次只能分配一个页面,而用户态程序可能申请了一个大于一个页面的空间。在这种情况下,操作系统会将用户态程序申请的空间分割成多个页面,然后逐个分配。这可能会导致内存碎片,因为操作系统可能会将一些小的内存块分配给用户态程序,而这些小的内存块可能会无法被其他进程使用。

为了解决这个问题,lazy lab实验中使用了缺页异常来实现懒惰分配。当用户态程序访问未分配的内存页面时,操作系统会引发缺页异常。然后,操作系统可以分配该页面并将其映射到用户态程序的地址空间。这种方法可以避免内存碎片,因为操作系统只会在需要时才分配内存页面。

当然,lazy lab实验只是lazy allocation思想在XV6操作系统中的应用。