zoukankan      html  css  js  c++  java
  • Windows核心编程(笔记12) 第十四章 探索虚拟内存 第十五章 在应用程序中使用虚拟内存 四

     50人阅读 评论(0) 收藏 举报

    第十四章 探索虚拟内存

      1.通过GetSystemInfo来获取主机相关信息。

      2.为了让32位应用程序在64位系统上运行,MS提供了WOW64这一模拟层,可用IsWow64Porcess或IsOs来判断某进程是否是这种形式运行。

      3.获取到的可用物理内存值会比内存实际大小小,这是因为系统在启动过程中为非页面缓冲池保留了一部分内存,这部分连内核都不能使用。

      4.一个进程的地址空间中被保存在内存中的那些页面,称为它的工作集。通过GetProcessMemoryInfo可以获得进程的当前工作集的大小和最大工作集的大小。结构体PROCCESS_MEMORY_COUNTERS_EX中的PrivateUsage表示通过new,malloc或VirtualAlloc函数显示分配的内存大小。

      5.削减程序对内存的需求将带来性能的提升。

      6.在VISTA中动态链接库每次都会被载入到不同的地址,这是因为一个名为地址空间布局随机化(ASLR)的新特性。这样可以防止黑客利用常用系统DLL的地址来攻击。当载入DLL时,系统内核会执行ASLR基地址重定位,经过修改后的页面为所有使用该DLL的进程所共享。通过开启/dynamicbase链接器开关,能让经过ASLR基地址重定位的页面为所有进程共享,从而提高内存的使用率。


    第十五章 在应用程序中使用虚拟内存

      1.Windows提供了三种机制来对内存进行操控:虚拟内存(管理大型对象数组或大型结构数组),内存映射文件(管理大型数据流,以及在多个进程间共享数据),堆(管理大量小型对象)。

      2.通过VirtualAlloc来给系统预定地址空间区域或调拨物理存储器:参数pvAddress是向下取整到64KB((据CPU而定)的整数倍,参数dwSize是按大取整到4KB(据CPU而定)的整数倍;参数fdwAllocationType指定是预定(MEM_RESERVE)还是调拨(MEM_COMMIT)还是两者兼有;参数fdwProtect是保护属性,一般多用PAGE_READWRITE,当区域的保护属性和将要调拨的物理存储器的保护属性一致时,处理效率会更高。

      3.如果打算预订一块区域用很长一段时间,那我们希望系统从尽可能高的内存地址来预定区域,这样可以防止在进程地址中间预定,从而避免可能引起的内存碎片。可以通过指定参数fdwAllocationType为MEM_TOP_DOWN来实现。

      4.注意:预定时保护属性不能用PAGE_WRITECOPY,PAGE_EXECUTE_WRITECOPY,PAGE_NOCACHE,PAGE_WRITECOMBINE,这些标记是用来调拨物理存储器的。

      5.调拨时,在已预订的区域中,我们必须告诉VirtualAlloc要调拨多少物理存储器给哪里。但无须一下子给整个区域都调拨物理存储器。

      6.Windows还提供了大页面支持,可以在处理大块内存时提升性能。通过GetLargePageMinimum可以确定分配粒度,若返回值为0则表示不支持。另外,需指定MEM_LARGE_PAGE标识,并满足三点要求:1,要分配的内存大小必须是获取到的分配粒度的整数倍;2,在分配时,必须预订和调拨一起执行;3,保护属性必须是PAGE_READWRITE。注:该分配必须要用户具有在内存中锁定页面的用户权限。

      7.windows认为大页面是不可换页的,必须驻留在内存中。

      8.用户权限是在登录时给予的,所以被赋予新的权限后,需要重新登录方能生效。

      9.当需判断何时调拨物理存储器时,可以采用SEH,先只预定地址空间,然后当程序试图访问尚未调拨物理存储器的内存地址时引发访问违规,SEH捕获异常,然后程序调拨物理存储器,再重新执行引发违规的指令,继续运行。这种方法所需工作量最少,而且程序又能全速运行,所以是最佳的。

      10.撤销调拨物理存储器及释放区域用VirtualFree,对其参数fdwFreeType分别指定MEM_DECOMMIT和MEM_RELEASE即可。注意:释放区域时dwSize必须填0,且必须释放为该区域预定的所有地址空间。但撤销调拨物理存储器时可以以页面为单位撤销,若dwSize传入0,则会撤销调拨给该区域的所有页面。

      11.可以通过VirtualProtect来改变已调拨的物理存储页的保护属性,也是以整个物理存储页为单位的。

      12.Windows提供重置物理存储器的内容的特性,它使得程序能够提高自身的性能。即我们告诉系统一个或几个物理存储页中的数据没有被修改过,那么当系统需要将该一个或几个内存页挪作它用时,它不会将页面的内容保存到页交换文件中。之后当我们试图在访问该虚拟地址的内容时,系统会给我们一个新的,全部清零的页面。注意:即使被占用的页面没有被清零或填充别的值,我们也不应该继续使用。

      13.重置存储器可以通过VirtualAlloc指定参数fdwAllocationType为MEM_RESET(该标识只能单独使用)来实现,注意:这种情况下,函数会把基地址向上取整到页面大小的整数倍(而不是向下),因为需要确保即使在基地址之前的同一页面中还有其他重要数据的情况下,也不会不小心把它们抛弃;大小也是同样的道理,需要向下取整到页面大小的整数倍,为了防止有效数据被抛弃。

      14.地址窗口扩展(AWE)用于让程序操控大块的不使用页交换文件的存储器。主要有俩目标:允许程序以一种特殊方式分配内存,系统保证不会将以这种方式分配的内存换出到磁盘中;允许程序访问比进程地址空间还要多的内存。

      15.实现AWE,需先通过VirtualAlloc指定参数fdwAllocationType为MEM_RESERVE | MEM_PHYSICAL来预定并指定该区域最终会以物理内存作为后备存储器,并把该区域作为地址窗口,然后通过AllocateUserPhyscicalPages(需要具有锁定页面的用户权限)来分配相应数量的内存页给进程(且只有该进程才能使用这些内存页,即不能进程间共享),再通过MapUserPhysicalPages把刚分配的内存页们指定给地址窗口。一旦内存块指定到了地址窗口,就可以用一个相对于地址窗口基地址的虚拟地址来引用其中的内存。

      16.注意:AWE要求所有映射到地址窗口的存储器必须是PAGE_READWRITE的,且不能使用VirtualProtect来改变页面属性。可以把分配的内存块给任意窗口地址,但不允许一个内存块同时出现在两个地址窗口中。

  • 相关阅读:
    MySQL中数据类型介绍
    Linux rpm命令详解
    Cloudera Manager集群官方默认的各个组件开启默认顺序
    全网最全Python学习路线图+14张思维导图,让python初学者不走弯路!
    python插入Elasticsearch操作
    最全的常用正则表达式大全(校验数字,字符,号码等)
    django.db.utils.OperationalError: (1193, "Unknown system variable 'storage_engine'")
    MVC/MVT/装饰器
    ModuleNotFoundError: No module named 'tools.utils'
    request +lxml 天眼查爬虫
  • 原文地址:https://www.cnblogs.com/sier/p/5676438.html
Copyright © 2011-2022 走看看