未加星标

win32应用程序性能测试-内存篇

字体大小 | |
[系统(windows) 所属分类 系统(windows) | 发布者 店小二04 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

win32应用程序性能测试-内存篇
本文主要讲述windows平台下应用程序性能测试的内存相关的知识,通过本文了解内存基本原理和分析内存占用问题。 一、内存是什么?

1. 内存分为物理内存和虚拟内存

物理内存指通过物理内存条而获得的内存空间,虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间)。

2. 两者都有系统约定的最大值

进程占用的内存一般是指物理内存,其中操作系统为每个进程的工作集定义了一个最小和最大工作集。每个进程的 工作集有最小工作集(20-50M)最大是45-345M

虚拟内存:每个32位的进程操作系统为其分配最大4G的线性虚拟地址空间,地址是从0X00000000~0XFFFFFFFF其中低的2G留给进程,高的2G留给系统。

3. 查看物理内存和虚拟内存

1) 电脑配置

例如我的电脑配置是 :如下,安装的内存是16G。查看资源监视器里显示,所以平时所说的内存占用是指物理内存。
win32应用程序性能测试-内存篇

2) 内存在资源管理器概念


win32应用程序性能测试-内存篇

例如这里进程: 物理内存(工作集)=可共享+专用工作集:是私人工作集中的内存数量与进程正在使用且可以由其他进程共享的内存数量的总和。

专用工作集:-是工作集的一个子集,专用工作集专门描述了某个进程正在使用的且无法与其他进程共享的内存数量。

提交大小:是为某进程使用而保留的虚拟内存的数量。

3) 虚拟内存查看

虚拟内存,用VMMAP工具查看。如下图


win32应用程序性能测试-内存篇
具体含义可以去网上搜索。其中虚拟内存有三种状态: 1) 自由(free)是指内存还未使用。

2)当申请内存使用VirtualAlloc传入MEM_RESERVE执行预留(reserved)操作。

3)当真正访问内存的数据才执行提交(committed),传入MEM_COMMINT参数。

二、系统如何管理内存

1. 系统使用PFN数据库

系统使用PFN(Page Frame Number)数据库来存储物理内存。分几类page list来存储,如下面的图


win32应用程序性能测试-内存篇
Freelist :可用来分配,但是含有脏数据 modified:以前属于某个进程,但是需要写入到后备存储,为备后面恢复 standby:跟进程关联,但是不计算在工作集里 zero:置0后用来分配

可缓存内存是指在smodified和standby上的,可用的内存是指在zero \free\standby lists,如果这个值小于800M的话。windows就会消减工作集,会导致整体性能变差。

2/ 操作过程

1)windows启动时,所有的内存全部是在free page list.当进程请求内存时,(我理解为发生一次错误,从zero page file)。进程退出,则会将内存还到free page list。

2)操作系统有两个线程会执行一些操作,一个是zero page thread,当要将free page移动到zeroed page时 进行置0 free page

3)第二个是modified page writer,将modified page list移动到standby page list时,进行第一次写出任何数据
win32应用程序性能测试-内存篇
win32应用程序性能测试-内存篇

页错误

1) 什么是页错误

访问数据时,进行虚拟地址映射到物理地址过程中,硬件检查页表时,发现所访问的页面不在内存,就产生异常 缺页异常,这个缺页异常就叫做页错误。操作系统会执行缺页异常处理程序:获得磁盘的地址、启动磁盘、将该页调入内存。如下图,是<<微软核心编程>>里例子,当访问的数据不在内存中就会发生一次fault,其中当访问page不在modified和standy里,则会发生HardPageFault。HardPageFault需要去系统的pagefile.sys里查找,这个查找过程会产生大量的IO操作,影响性能。
win32应用程序性能测试-内存篇

2) 页错误的类型

Transition:是指访问的page是指在modify或者stadby page list上DemandZero:进程请求内存是,调用是zero page listHardPageFault:访问的page不在工作集里,需要去磁盘pagefile去查找copy on write:写入copy-on-write page。例如你要hook一个kernel上的函数,就是操作kernel上的page,需要先拷贝一份,这样不会影响其它进程使用kernel上的函数,这个操作就会发生一次copy on write错误


win32应用程序性能测试-内存篇

内存的分配API

1)利用HeapAlloc方法或C/C++运行时中的malloc或new来进行堆内存分配。

2)利用VirtualAlloc方法从系统中直接分配内存。VirtualAlloc是Windows提供的API,通常用来分配大块的内存

3)由内核通过CreateFile, CreateEvent, or CreateThread等Kernel32 APIs,来代表应用程序进行处理

4)利用User32和Gdi32 APIs来处理GDI和USER。(默认情况下,每一个线程都有10,000处理(10,000 handles)配额)

三、如何优化内存占用高的问题

1. 刷内存

刷内存SetProcessWorkingSetSize

1) 原理

函数用来设置应用程序最小和最大的运行空间,只会保留需要的内存,例如我们的部分exe里是有刷内存,这里设置的最小8M,最大14M
win32应用程序性能测试-内存篇

2) 缺点

刷内存只是将可能暂时不需要工作集swap出去,如果业务又再需要,需从虚拟内存的pagefile里调用过来,这个过程反而降低系统性能,所以不推荐使用

2. 减少页错误

这里推荐的操作是预处理,减少随机IO等。

3. 查找占用不合理和分配不合理的地方

1) 例子:某个dll 申请内存不合理

分析过程 1) 抓取对应exe启动过程中VirtualAlloc。 2) 查看启动过程中过程中VirtualAlloc分配的类型是AIFO【AIFO是指在此阶段分配但未释放,这种就是可疑的分配点】。发现其中有一段每次分配495K
win32应用程序性能测试-内存篇
3)
win32应用程序性能测试-内存篇

4)查看源码,发现这里是每隔3S,去查询系统所有进程的一个快照,所以每次大小都有接近500K。而且场景的触发频率非常高,每隔1S检测一次,后面跟开发核实,这里的逻辑不应如此设计

5)通过这个问题,我们可以去系统检索一个分配内存大的函数,例如CreateToolhelp32Snapshot,是不是所有触发逻辑合理,轮询调用是非常不合理,应该要规避,而且这个代码是常驻的。这个留在后面形成相应的规则

2. 例子:是内存泄露还是?

例子:某个版本的资源挂机突然VM增加,是内存泄露还是? 1) 现象:如下图一个内部版本,在某个长时间挂机,突然出现在1个小时和4个小时后,内存增长10M的样子。时间跨度长,如何获取增长时的内存分配堆栈?


win32应用程序性能测试-内存篇

2)复现过程:

安装同样的版本,发现本地也会出现VM从32M最后涨到50M的情况。 设计trace的日志

Xperf -on PROC_THREAD+LOADER+CSWITCH+DISPATCHER+VIRT_ALLOC -stackwalkCSwitch+ReadyThread

xperf -start HeapSession -heap -Pids 18908 -BufferSize 1024 -MinBuffers 128 -MaxBuffers 128 -stackwalkHeapAlloc+HeapRealloc

注:第二条是开启heapsession来trace指定进程的heapalloc。整个过程etl太大,全部需要输出到文件模式

分析trace过程的分配。 如下图,查看到这个过程有几个分配大的点。其中有一个1M到4M,增长3M的情况和对应的堆栈。
win32应用程序性能测试-内存篇

其中0xfd10000这个对象分配3.176M,这个堆栈全部都是系统的API


win32应用程序性能测试-内存篇
对应CPU调度图来查看是什么原因导致这个分配,这里表现是一个TPKTT.dll
win32应用程序性能测试-内存篇
查看当时的内存dump,查看0xfd10000对象,调用的堆栈是文件监控里
win32应用程序性能测试-内存篇
win32应用程序性能测试-内存篇
结合上面,怀疑是文件监控导致的,但是跟开发确认文件监控很久未变更,而且文件监控是底层逻辑,所有业务会触及。另一方面,查看TPKTT.dll相关的信息,他们的里面的逻辑没有泄露点 是不是挂机的现象和我这不一样,同样在挂机的机器上抓trace日志,最后问题点是一样的 再次分析内存分配的堆栈,向前查看,发现调用文件监控逻辑前有一个Loadlibrary的操作,而且TPKTT.dll的大小正好也是3M多
win32应用程序性能测试-内存篇
开发再次排查他们的逻辑,原来在静默1个小时后,会触发引擎的TPK的逻辑,这里,概会增加10到13M的样子,所以RTP VM增加属于业务的需要,引擎库加载需要内存。这个逻辑触发在70分钟到90分钟之间。因为我们的挂机以前只挂1个小时,这次是因为验证其它问题,所以挂机时间长出现这个问题。经过2天的定位,终于确认这次增长。 四、结尾

性能里调优内存涉及的点比较多,上面几个例子只是部分。建议平时先建设基础基准数据,有业务增加及时定位。

附我们内存优化的一些方向:


win32应用程序性能测试-内存篇

参考文章:

https://blogs.msdn.microsoft.com/tims/2010/10/29/pdc10-mysteries-of-windows-memory-management-revealed-part-two/


win32应用程序性能测试-内存篇

【TMQ新书专栏】https://weidian.com/?userid=984448577

版权所属,禁止转载

本文系统(windows)相关术语:三级网络技术 计算机三级网络技术 网络技术基础 计算机网络技术

主题: 性能测试数据WindowsC++CPU定位微软2G数据库4G
分页:12
转载请注明
本文标题:win32应用程序性能测试-内存篇
本站链接:http://www.codesec.net/view/519691.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 系统(windows) | 评论(0) | 阅读(34)