【问题标题】:Why does integer value take 72 bytes of memory? [duplicate]为什么整数值占用 72 字节的内存? [复制]
【发布时间】:2011-09-09 07:40:36
【问题描述】:

可能重复:
What is the overhead of using PHP int?

谁能解释一下,为什么在 PHP 中创建一个整数需要 72 个字节?

var_dump(memory_get_usage()); //49248 bytes  
$a = 255;  
var_dump(memory_get_usage()); // 49320 bytes

【问题讨论】:

  • PHP 是一种欧洲语言。该变量需要健康保险、养老金、社会安全号码......(说真的 - 好问题!)
  • 啊哈!找到了!享受。这可能不是“确切”的重复,因为它没有说明为什么需要空间开始,但它确实解决了有关 32 位和 64 位平台上大小差异的其他问题。我不确定变量本身(例如不仅仅是值)是否也会影响内存使用...?
  • 每次你创建一个 int 时它实际上增加了 72 个字节吗?
  • @Hannesh 每个整数都是一个新值(“对象”)——为什么不呢? Python“缓存”小整数。 PHP 也可能会这样做,但如果这样做,255 可能会超出范围。 (我不知道是不是这样)。

标签: php memory


【解决方案1】:

我没有广泛的 PHP 内部知识,但概念是,当您创建一个具有整数值的变量时,PHP 会在内部分配一个结构(这种结构通常称为 variants)能够保存语言中的任何类型的值(包括对象类型、函数等)。这必然需要超过 4 个字节。

除此之外,剩下的问题是为什么是 72(而不是例如 42)?为了回答这个问题,我们不仅需要检查 C 源代码(查看确切分配了什么以及它的内存占用是多少),还要检查 memory_get_usage 的实现(查看它计算内存使用量)。

更新:我觉得我需要更多地强调“它如何计算内存使用量”部分。

新变量的分配完全有可能导致 PHP 的内存分配器从 C 堆中保留一块内存,该内存块远大于满足变量分配请求所需的内存块(它也可以决定将来保留该内存即使在你之后使用,例如 unset 变量)。

如果memory_get_usage 想要将整个内存块计算为“已使用”,那么您甚至可以看到一个简单的整数变量导致使用率上升,例如 1K(如果事情像我到目前为止所描述的那样简单,那么额外的整数分配将不会导致内存使用量增加)。

我的意思是,在您完全定义预期结果之前,您不能将内存使用结果称为意外。如果不查看memory_get_usage 的来源,这是不可能的。

【讨论】:

  • 好的。让我们假设创建一个变量 4 个字节用于实际数据 2-4 个字节用于数据类型(zval) 2-4 个字节用于 refcount 2-4 个字节 fot is_ref 我还认为创建第一个变量可能需要资源来创建范围和符号的内部结构表但创建另一个 var $b = 255 会导致另外 72 个字节的使用... O_o
  • 在 codepad.org 上,整数需要 188 个字节:codepad.org/51oCNQM6 即使我调用 unset(),内存也没有被释放!
  • @user603003 是一个64位的平台,帖子里的那个是32位的。有一个 SO question 涵盖了这个......我当然找不到。它与指针大小以及填充和对齐有关。
  • @zim32:更新了答案,请看一下。
  • 看起来可能是变种。但为什么要添加另一个变量?说 $b = 255 会导致另外 72 个字节...
【解决方案2】:

这可能与 PHP 分配内存的方式有关。这些文件不会被编译成二进制文件,因此它们不会将四个字节压入堆栈或在堆上分配,而是在虚拟堆栈上分配内存。

【讨论】:

    【解决方案3】:

    设置任何变量都会占用一定数量的内存,因此您可以执行以下操作而不会出现任何错误:

    $a = 100;
    //...then later in the code
    $a = 100000;
    //or
    $b = "hello";
    //...then later in the code
    $b = "hello world this is a long string to show how long a string can be.";
    

    这也可能是因为 PHP 是一种预处理语言,而不是一个将您的代码转换为二进制然后运行二进制代码的程序。

    【讨论】:

      猜你喜欢
      • 2014-03-20
      • 2022-08-05
      • 1970-01-01
      • 2011-04-26
      • 2021-03-13
      • 2016-08-29
      • 2011-07-06
      • 2022-07-06
      相关资源
      最近更新 更多