软件测试中的压力测试

发表于:2008-5-20 13:20

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:网络转载

        正如您稍后将在本专栏中看到的,为您提供了大量的附加信息。由于压力器工具要修改运行它的计算机的状态,因此,这些压力器的所有输出在一定程度上是不必要的。要监控的最重要的数据是任何给定时间的可用虚拟内存量。

        在主 while 循环和次循环中,我将经过的时间传入 TimeSpan 对象,并计算一个随机百分比,如下所示:

while (DateTime.UtcNow < stopTime) // main loop
{
  for (int cycle = 0; cycle < 8; ++cycle)
  {
    // get the elapsed time so far
    TimeSpan elapsedTime = DateTime.UtcNow - startTime;

    // compute a random percentage
    double randomPct = (r.NextDouble() * (0.70 - 0.10)) + 0.10;
    if (randomPct < 0.10 || randomPct > 0.70)
      throw new Exception("Bad random pct");

        这里我对 EatMem 进行了硬编码,以便它可以使用一个标准映射技术生成 0.10 到 0.70 之间的一个随机数字。该方法调用 Random.NextDouble 将返回范围 [0.0, 1.0](这意味着大于或等于 0.0 而小于 1.0)中的一个数字。如果我用 (0.70 - 0.10) = 0.60 乘以该间隔,则该间隔将映射为范围 [0.0, 0.6] 中的一个随机数字。然后,如果我加上 0.10,则最终的间隔将映射为 [0.10, 0.70]。

    下一步是计算要利用的字节数:

// compute number of bytes to eat
GlobalMemoryStatus(ref memStatusBuffer);
uint numBytesToEatInBytes =
  (uint)(randomPct * memStatusBuffer.dwAvailVirtual);
uint numBytesToEatInKB =
  numBytesToEatInBytes / basicUnit;

        我使用 C# 互操作机制调用 Win32 GlobalMemoryStatus 方法,以便获取当前可用的虚拟内存字节数。请注意,我传入了一个指向 MEMORYSTATUS 结构的引用,这是因为初始 C++ 签名需要一个指向该结构参数的指针。或者要以托管代码表示,我传入一个对结构的引用,因为该结构将更改。当内存状态信息存入 memStatusBuffer 对象后,我可以将它拿出来使用。我可以确定要分配的字节数,方法是用在前一步中计算的随机百分比乘以可用字节数。为进行显示,我也将该结果转换成千字节。

        现在,我准备尝试用 GlobalAlloc 函数分配内存(请参阅 图 4)。GlobalAlloc 函数接受两个参数。第一个参数是一个标志,指定若干种分配方式其中之一:

GMEM_FIXED    = 0x0000 Allocates fixed memory.
GMEM_MOVEABLE = 0x0002 Allocates movable memory.
GMEM_ZEROINIT = 0x0040 Initializes memory contents to 0.

GPTR = 0x0040 Combines GMEM_FIXED and GMEM_ZEROINIT.
GHND = 0x0042 Combines GMEM_MOVEABLE and GMEM_ZEROINIT.

        这里我使用 GPTR = 0x0040 来分配初始化为零的固定内存。

Figure 4 Allocate Memory
// allocate memory
uint GPTR = 0x0040; // Combines GMEM_FIXED and GMEM_ZEROINIT
IntPtr p = GlobalAlloc(GPTR, numBytesToEatInBytes);
if (p == IntPtr.Zero)
{
  string time = elapsedTime.Hours.ToString("00") + ":" +
         elapsedTime.Minutes.ToString("00") + ":" +
         elapsedTime.Seconds.ToString("00");
  Console.Write("{0,8}", time);
             
  Console.WriteLine("   GlobalAlloc() failed.  Trying again");
  --cycle;
  continue;
}

        GlobalAlloc 的第二个参数是要分配的字节数。如果该分配成功,则 GlobalAlloc 返回一个指向所分配内存第一个地址的 IntPtr。如果分配失败,则返回值是 IntPtr.Zero(几乎等同于非托管代码 null)。该分配可能由于若干种原因而失败;实际上,我预料分配在某些压力情况下会失败。这样,我就不会引发一个异常,而只是打印一个警告信息,再次尝试。GlobalAlloc 函数分配来自堆的指定字节数。

        处理内存分配时,需要注意三个组件:物理内存、页文件和虚拟内存。仅当指令在 RAM 中时,程序才可以执行该指令。RAM 有固定的大小;近年来,桌面计算机 RAM 的大小通常为 512MB。如果一个程序小于 RAM 的大小,则整个程序可以加载到内存中。虚拟内存的思路是允许运行大于 RAM 的程序。页文件供操作系统在必要时将代码换入内存、换出内存。默认的原始页文件大小是 RAM 大小的 1.5 倍,但页文件大小在必要时可以增加。虚拟内存的最大值是不同的,但 32 位 Windows® 版本通常为 2GB。

        分配内存之后,我需要获取更新的内存状态,这样我就可以显示不同的诊断数据:

// get current memory status
GlobalMemoryStatus(ref memStatusBuffer);
uint availablePhysicalInKB =
 memStatusBuffer.dwAvailPhys / (uint)basicUnit;
uint availableVirtualInKB =
 memStatusBuffer.dwAvailVirtual / (uint)basicUnit;
numBytesToEatInBytes =
 (uint)(randomPct * memStatusBuffer.dwAvailVirtual);
numBytesToEatInKB = numBytesToEatInBytes / basicUnit;

63/6<123456>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号