减少内存使用阵列和SplFixedArray [英] Decreasing memory usage for array and SplFixedArray

查看:118
本文介绍了减少内存使用阵列和SplFixedArray的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做阵列之间一些基准() SplFixedArray(),我碰到奇怪的行为。首先,看看我的简单测试(实际上只是编辑的版本从互联网上,对不起,我现在无法找到原始出处):

I was doing some benchmarks between array() and SplFixedArray() and I run into strange behaviour. At first, look at my simple test (it's actually just edited version from internet, sorry, I can't find original source now):

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()测试后立即未设置() previous的之一,看到输出:

Results were kind of expected - SplFixedArray() was faster in writing and little bit slower in reading. Things starts to be strange when I put another same SplFixedArray() test right after unset() of previous one, see the output:

> 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

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

Why second test use less memory than first one? And hey, I try to add next test and:

> 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 的之后。在这里我的问题是显而易见的:如何是可能的,所以,当我未设置previous对象,并创建新的,使用的内存较低它与正常阵列的作品? ()了。

So I of course try to add more and more and after few more decreasing stoped on 512 kB. My question here is obvious: How it is possible and why that when I unset previous object and create new one, used memory is lower? And it works with normal array() too.

推荐答案

我们需要进入发动机如果我们想明白这一点。更好:的Zend / zend_alloc.c(在​​Zend内存管理器)内

We need to go into the engine if we want to understand this. Better: inside of Zend/zend_alloc.c (The Zend Memory Manager).

由存储器管理器分配的存储器被分成 256 KB的块

The memory allocated by the memory manager is split into chunks of 256 KB.

一旦释放SPLFixedArray,仅存储器的第一连续块被释放。那里总是保持256 KB(一些变量),然后积累的块。 (它的工作原理从操作系统分配的内存接下来将只是靠近此内存块)

Upon freeing the SPLFixedArray, only the first contiguous chunk of memory is freed. There always remains a block of 256 KB (some variables) which then accumulates. (which works as the next from the OS allocated memory will be just adjacent to this memory block)

此内存段然后标记为空闲并用接下来的可能时,而不是分配从OS新的存储时间。 (如果需要一些内存附加)

This memory segment is then marked as free and used the next time when possible instead of allocating new memory from the OS. (and if necessary some memory is appended)

但随着块的256 KB总是释放至少有一个,我们总是会发现256 KB的区别。

But as at least one block of 256 KB is always freed, we always will notice a difference of 256 KB.

当你想测量内存使用情况,我真的会使用 memory_get_usage(假),因为它表明你有多少内存PHP(Zend的≠)的需求。 (这对计算唯一的 memory_limit的 INI设置)

When you want to measure memory usage, I really would use memory_get_usage(false) as it indicates you how much memory PHP (≠ Zend) needs. (the only thing which counts against the memory_limit ini setting)

这篇关于减少内存使用阵列和SplFixedArray的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆