作为测试人员角度研究了很多内存相关的东西,当我在51发了博客后,通过反馈,针对我的2篇博客在这里进行补充。
CPU,进程:
http://www.51testing.com/?viewspace-832192
内存:
http://www.51testing.com/?viewspace-832362
首先先讨论内存的相关知识,当我在以上博文提到内存泄漏和频繁的使用new和delete的时候,在同事间讨论了下,实际运用中能够很好的规避方法。
我首先我研究了同事使用的Lookaside List(旁视列表):
旁视列表是一组事先分配的相同尺寸的内存块。当有内存分配请求的时候,系统会遍历这个列表寻找最近的未分配的块。如果未分配的块找到了,分配请求就很快被满足。否则系统必须从分页或不分页内存池去分配。根据列表中分配行为发生的频率,系统会自动调整未分配块的数量来满足分配请求,分配的频率越高,会有越多的块被存储在旁视列表中。当开始从旁视列表分配内存的时候,将获得这些预分配内存块的指针。 保存内存位置的方法,首先我们每次
可以将旁视列表想象成一个内存容器,在初始时,向Windows申请了一块比较大的内存,以后每次申请内存时,不是向Windows申请内存,而是向lookaside对象申请内存.lookaside会智能的避免产生内存漏洞,当其内部有大量未使用的内存时,会自动释放内存给Windows
一般在如下两种情况下使用:1、每次申请固定大小的内存;2、申请和回收操作十分频繁
而我是这么理解,new的时候,把new的地址存进声明为未使用的列表中,当我们用到内存的时候,首先去此列表里面找到没有用到的内存地址,假如有空闲的地址,就把其调来使用,同时把它从未使用的列表中删除,把他加入进声明为已使用的列表。如果未使用链表里为空,就再new一部分内存出来。这样就是一个链表是使用中的,另一个链表是未使用的 。同时我们需要注意的就是跟踪这个内存的走向,在那个地方delete。这样管理的时候需要注意当你用了列表的元素后,不改它的标识位或者不把他移动到别的列表时,就会出现野指针了。
针对内存泄漏,大多的情况就是就是new的没有delete,还有容易泄露的地方是new的一个数组,但是用delete去删除。
然后是关于我写第一个博文时候,说到的信号量的部分,因为工作中信号量用的实在很少,一般用互斥就能够完成大部分的工作。
互斥量用于线程的互斥,信号量用于线程的同步。
这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。
互斥量值只能为0/1,信号量值可以为非负整数。
也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。
互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。
不知道别的业务,在写性能测试脚本的时候由于很多时候会产生做同样事情的上百个线程,然后几个管理性质的线程的情况,这时候基本上除了管理线程,每个线程都是独立的,只有出现写文件,修改同一变量和访问数据库的时候会出现同时访问资源的现象,使用互斥的锁就能够让资源不会同时被2个线程修改。在更深理解了信号量和互斥的区别后,我就把信号量用在性能测试的一个概念‘集合点’上。因为我需要让很多分布式的客户端同一时间起跑去压一个资源,所以我需要服务器每个管理分布式客户端的线程都要做到尽量小误差的下发冲包命令,这样我就能很准确的知道在每个集合点的并发数对服务器的压力情况是多少了。