首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >减少数组和SplFixedArray的内存使用量

减少数组和SplFixedArray的内存使用量
EN

Stack Overflow用户
提问于 2014-01-30 10:31:52
回答 1查看 974关注 0票数 5

我在array()SplFixedArray()之间做了一些基准测试,我遇到了一些奇怪的行为。首先,看看我的简单测试(它实际上是从互联网上编辑出来的,对不起,我现在找不到原始的源代码):

代码语言:javascript
复制
function formatMemoryUsage($usage) {
   $unit = array(' B', 'kB', 'MB', 'GB', 'TB');
   $factor = floor((strlen($usage) - 1) / 3);

   return sprintf('%.2f %s (%d bytes) ', $usage / pow(1024, $factor), $unit[$factor], $usage);
}

for($size = 1000; $size < 100000; $size *= 2) { 
   echo PHP_EOL . '> Testing size: ' . number_format($size) . PHP_EOL; 
   echo '   Array()' . PHP_EOL;

   for($s = microtime(true), $m = memory_get_usage(true), $container = Array(), $i = 0; $i < $size; $i++) $container[$i] = null; 
      echo '      - Write         - time   : ' . str_pad(microtime(true) - $s, 20, '0') . '     - memory: ' . formatMemoryUsage(memory_get_usage(true) - $m) . PHP_EOL; 

   $s = microtime(true); 
   foreach ($container as $key => $value) {
      $void = $value;
   }
   echo '      - Read          - time   : ' . str_pad(microtime(true) - $s, 20, '0') . PHP_EOL;

   unset($container);

   echo '   SplFixedArray()' . PHP_EOL;

   for($s = microtime(true), $m = memory_get_usage(true), $container = new SplFixedArray($size), $i = 0; $i < $size; $i++) $container[$i] = null; 
   echo '      - Write         - time   : ' . str_pad(microtime(true) - $s, 20, '0') . '     - memory: ' . formatMemoryUsage(memory_get_usage(true) - $m) . PHP_EOL; 

   $s = microtime(true); 
   foreach ($container as $key => $value) {
      $void = $value;
   }
   echo '      - Read          - time   : ' . str_pad(microtime(true) - $s, 20, '0') . PHP_EOL; 

   unset($container);
} 

结果是预期的-- SplFixedArray()的书写速度更快,阅读速度更慢。当我在上一次SplFixedArray()测试的unset()之后放置另一个相同的测试时,情况开始变得奇怪,请参见输出:

代码语言:javascript
复制
> Testing size: 64,000
   Array()
      - Write         - time   : 0.009041070938110400     - memory: 7.50 MB (7864320 bytes) 
      - Read          - time   : 0.004010915756225600
   SplFixedArray()
      - Write         - time   : 0.004639148712158200     - memory: 1.75 MB (1835008 bytes) 
      - Read          - time   : 0.005971908569335900
   SplFixedArray()
      - Write         - time   : 0.005653858184814500     - memory: 1.50 MB (1572864 bytes) 
      - Read          - time   : 0.006288051605224600

为什么第二次测试比第一次测试使用的内存少?嘿,我试着添加下一个测试:

代码语言:javascript
复制
> Testing size: 64,000
   Array()
      - Write         - time   : 0.008963823318481400     - memory: 7.50 MB (7864320 bytes) 
      - Read          - time   : 0.004142045974731400
   SplFixedArray()
      - Write         - time   : 0.005026102066040000     - memory: 1.75 MB (1835008 bytes) 
      - Read          - time   : 0.005756139755249000
   SplFixedArray()
      - Write         - time   : 0.004483938217163100     - memory: 1.50 MB (1572864 bytes) 
      - Read          - time   : 0.005591869354248000
   SplFixedArray()
      - Write         - time   : 0.004633903503418000     - memory: 1.25 MB (1310720 bytes) 
      - Read          - time   : 0.005697011947631800

因此,我当然试着增加越来越多,在很少的减少之后,在512 kB上停止。我在这里的问题很明显:是如何可能的?为什么当我取消设置以前的对象并创建新的对象时,使用的内存更少?,它也适用于普通的array()

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-04 18:57:52

如果我们想了解这一点,我们需要进入引擎。更好:在C( Zend内存管理器)内部。

内存管理器分配的内存被分成几个256 KB块。

在释放SPLFixedArray时,只释放第一个连续的内存块。。始终保留一个256 KB的块(一些变量),然后进行累积。(操作系统分配的内存中的下一个内存将与此内存块相邻)

这个内存段然后是标记为自由,并在下一次可能时使用,而不是从操作系统分配新内存。(如果有必要,还会追加一些内存)

但是,由于至少有一个256 KB的块总是被释放,所以我们总是会注意到256 KB的差异。

当您想要测量内存使用量时,我确实会使用memory_get_usage(false),因为它指示您需要多少内存≠(≠Zend)。(唯一与memory_limit ini设置相对应的东西)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21453915

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档