XSLT存档  

不及格的程序员-八神

 查看分类:  ASP.NET XML/XSLT JavaScripT   我的MSN空间Blog

关于内存管理

32 位 Microsoft Windows上的每个进程都有其自己的虚拟地址空间,可实现高达 4 GB 内存的寻址。 64 位Windows的每个进程都有 8 TB 的虚拟地址空间。 进程的所有线程都可以访问其虚拟地址空间。 但是,线程无法访问属于另一个进程的内存,从而防止进程被另一个进程损坏。

虚拟地址空间 (内存管理)

进程的虚拟地址空间是它可以使用的虚拟内存地址集。 每个进程的地址空间是私有的,除非其他进程共享,否则无法访问该地址空间。

虚拟地址不表示内存中对象的实际物理位置;相反,系统为每个进程维护 一个页表 ,这是一个内部数据结构,用于将虚拟地址转换为其相应的物理地址。 每次线程引用地址时,系统都会将虚拟地址转换为物理地址。

32 位Windows的虚拟地址空间大小为 4 GB (GB) ,分为两个分区:一个分区供进程使用,另一个用于系统使用。 有关 64 位Windows中的虚拟地址空间的详细信息,请参阅 64 位Windows中的虚拟地址空间

默认情况下,基于 64 位 Microsoft Windows 的应用程序具有几 TB 的用户模式地址空间。 有关精确值,请参阅Windows和Windows服务器版本的内存限制。 但是,应用程序可以指定系统应为低于 2 GB 的应用程序分配所有内存。 如果满足以下条件,此功能适用于 64 位应用程序:

  • 2 GB 地址空间已足够。
  • 代码包含许多指针截断警告。
  • 指针和整数可以自由混合。
  • 代码使用 32 位数据类型具有多态性。

所有指针仍是 64 位指针,但系统可确保每个内存分配都低于 2 GB 限制,以便应用程序截断指针时不会丢失任何重要数据。 指针可以截断为 32 位值,然后通过符号扩展或零扩展名扩展到 64 位值。

若要指定此内存限制,请使用 /LARGEADDRESSAWARE:NO 链接器选项。 请注意,对于 ARM64 二进制文件 ,将忽略 /LARGEADDRESSAWARE:NO 。 但是,请注意,使用此选项时可能会出现问题。 如果生成使用此选项的 DLL,并且 DLL 是由不使用此选项的应用程序调用的,则 DLL 可能会截断其高 32 位的 64 位指针。 这可能会导致应用程序失败,没有任何警告。

虚拟地址空间和物理存储

物理存储和每个进程的虚拟地址空间都组织成 页面、内存单位,其大小取决于主计算机。 例如,在 x86 计算机上,主机页大小为 4 KB。

为了最大程度地提高其管理内存的灵活性,系统可以将物理内存页移入磁盘上的分页文件或从磁盘上的分页文件移动。 在物理内存中移动页面时,系统会更新受影响进程的页映射。 当系统需要物理内存中的空间时,它会将最近使用最少的物理内存页移动到分页文件。 系统对物理内存的操作对应用程序完全透明,应用程序仅在虚拟地址空间中运行。

  • working set
  • paged pool
  • nonpaged pool
  • pagefile

The working set is the amount of memory physically mapped to the process context at a given time.
Memory in the paged pool is system memory that can be transferred to the paging file on disk (paged) when it is not being used.
Memory in the nonpaged pool is system memory that cannot be paged to disk as long as the corresponding objects are allocated.
The pagefile usage represents how much memory is set aside(预留) for the process in the system paging file.
When memory usage is too high, the virtual memory manager pages selected memory to disk.
When a thread needs a page that is not in memory, the memory manager reloads it from the paging file.

 

工作集

当进程引用当前不在其工作集中的可分页内存时,将发生 页面错误 。 系统页错误处理程序尝试解决页面错误,如果成功,则会将页面添加到工作集。 (访问 AWE 或大型页面分配永远不会导致页面错误,因为这些分配不可分页 .)

必须通过从页面的后盾存储中读取页面内容(即系统分页文件或进程创建的内存映射文件)来解决硬页错误。 无需访问后盾存储即可解决 软页面故障 。 出现软页面错误时:

  • 页面位于其他进程的工作集中,因此它已驻留在内存中。
  • 页面处于过渡状态,因为它已从使用页面且尚未重新用途的所有进程的工作集中删除,或者由于内存管理器预提取操作而已驻留。
  • 进程首次引用分配的虚拟页, (有时称为 需求零故障) 。

由于以下操作,可以从进程工作集中删除页面:

  • 该过程通过调用 SetProcessWorkingSetSize、SetProcessWorkingSetSizeEx 或 EmptyWorkingSet 函数来减少或清空工作  。
  • 进程在未锁定的内存范围上调用 VirtualUnlock 函数。
  • 该过程使用 UnmapViewOfFile 函数取消映射文件的映射视图。
  • 内存管理器会剪裁工作集中的页面,以创建更多可用内存。
  • 例如,内存管理器必须从工作集中删除一个页面,以便为新页腾出空间 (,因为工作集的最大大小为) 。

如果多个进程共享一个页面,则从一个进程的工作集中删除页面不会影响其他进程。 从使用该页面的所有进程的工作集中删除页面后,页面将成为 转换页。 转换页仍缓存在 RAM 中,直到某个进程再次引用页面或重新调整 ((例如,填充零,并提供给另一个进程) )。 如果转换页自上次写入磁盘 ((即页面为“脏”)) ,则必须将页面写入其后盾存储区,然后才能重新调整其用途。 系统可能会在此类页面可用后立即开始将脏转换页写入其后盾存储。

每个进程都有一个影响进程的虚拟内存分页行为的最小和最大工作集大小。 若要获取指定进程的工作集的当前大小,请使用 GetProcessMemoryInfo 函数。 若要获取或更改最小和最大工作集大小,请使用 GetProcessWorkingSetSizeEx 和 SetProcessWorkingSetSizeEx 函数。

进程状态应用程序编程接口 (PSAPI) 提供了许多函数,这些函数返回有关进程工作集的详细信息。 有关详细信息,请参阅 工作集信息

页面状态

状态描述
  Free 该页既未提交也不保留。 进程无法访问该页面。 它可供保留、提交或同时保留和提交。 尝试读取或写入免费页面会导致访问冲突异常。
进程可以使用 VirtualFree 或 VirtualFreeEx 函数释放其地址空间的保留页或已提交页,并将其返回到免费状态。
  预留 该页已保留以供将来使用。 其他分配函数不能使用地址范围。 该页不可访问,并且没有与之关联的物理存储。 它可供提交。
进程可以使用 VirtualAlloc 或 VirtualAllocEx 函数来保留其地址空间的页面,稍后提交保留页。 它可以使用 VirtualFree 或 VirtualFreeEx 取消提交页面,并将其返回到保留状态。
已提交     内存费用已从磁盘上的 RAM 和分页文件的总体大小分配。 页面可访问,访问由 内存保护常量之一控制。 系统仅在首次尝试读取或写入该页时,才会将每个提交的页面初始化并加载到物理内存中。 当进程终止时,系统会释放已提交页面的存储。
进程可以使用 VirtualAlloc 或 VirtualAllocEx 从保留区域提交物理页。 它们还可以同时保留和提交页面。
GlobalAlloc 和 LocalAlloc 函数分配具有读/写访问权限的已提交页面。
Memory charges have been allocated from the overall size of RAM and paging files on disk.

 

内存保护

属于进程的内存由其专用虚拟地址空间隐式保护。 此外,Windows使用虚拟内存硬件提供内存保护。 此保护的实现因处理器而异,例如,进程地址空间中的代码页可以标记为只读,并受用户模式线程修改的保护。

有关属性的完整列表,请参阅 内存保护常量

写入上的复制保护

复制写入保护是一种优化,允许多个进程映射其虚拟地址空间,以便它们共享物理页,直到其中一个进程修改页面。 这是一种称为 惰性评估的技术的一部分,它允许系统在绝对必要之前不执行操作来节省物理内存和时间。

例如,假设两个进程将同一 DLL 中的页面加载到其虚拟内存空间中。 这些虚拟内存页映射到这两个进程的相同物理内存页。 只要两个页面都无法写入这些页面,它们就可以映射到和共享相同的物理页面,如下图所示。

boxes and arrows of process 1 and 2 pages mapped to same physical memory

如果 Process 1 写入其中一个页面,则物理页的内容将复制到另一个物理页,并且虚拟内存映射将更新为 Process 1。 这两个进程现在在物理内存中都有自己的页面实例。 因此,一个进程无法写入共享物理页,另一个进程无法查看更改。

boxes and arrows of processes and physical memory remapping

加载应用程序和 DLL

加载同一个基于Windows应用程序的多个实例时,每个实例在其自己的受保护虚拟地址空间中运行。 但是,它们的实例处理 (hInstance) 通常具有相同的值。 此值表示应用程序在其虚拟地址空间中的基址。 如果每个实例都可以加载到其默认基址中,则可以使用复制写入保护映射到其他实例并共享同一物理页。 系统允许这些实例共享相同的物理页面,直到其中一个实例修改页面。 如果出于某种原因,这些实例之一无法加载到所需的基址中,它将接收其自己的物理页。

DLL 是使用默认基址创建的。 使用 DLL 的每个进程都会尝试在 DLL 的默认虚拟地址处将 DLL 加载在其自己的地址空间中。 如果多个应用程序可以在其默认虚拟地址加载 DLL,则可以共享 DLL 的相同物理页。 如果出于某种原因,进程无法在默认地址加载 DLL,它将加载到其他位置的 DLL。 在写入时复制保护会强制将 DLL 的某些页面复制到此过程的不同物理页中,因为对跳转指令的修复是在 DLL 页中编写的,并且对于此过程,它们将有所不同。 如果代码节包含对数据节的许多引用,这可能会导致整个代码节复制到新的物理页。

 

posted on 2023-02-11 12:00  不及格的程序员-八神  阅读(48)  评论(0编辑  收藏  举报