草庐IT

php - 与 PHP 5.6 相比,我在 PHP 7 中面临更多的内存消耗

coder 2023-06-14 原文

当我做基准测试时,我发现 PHP 7 使用的内存比 PHP 5.6 多。

所以,我做了一个测试。我运行的脚本仅包含:

  $a=10;

以下是我在没有任何模块的情况下使用 PHP CLI 时使用的内存的结果 (php -n)

php 5.6 = 222600 Bytes
php 7.0 = 350448 Bytes

* PHP 5.6.23 (cli) (built: Jun 22 2016 12:13:15)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies 

* PHP 7.0.9 (cli) (built: Jul 20 2016 10:47:41) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies

环境是

  • 操作系统:窗口 10
  • 服务器:IIS(虽然我使用的是 CLI,而不是服务器),具有快速 cgi
  • 机器:64 位
  • php-5.6.23-nts-Win32-VC11-x64
  • php-7.0.9-nts-Win32-VC14-x64

谁能解释我为什么得到这个结果?


附加测试

按照@gordon 的建议使用此代码,

$i=0;
while ($i++ < 100000) ;

php 5.6:227408 字节

php 7.0:386640 字节

我用这段代码确定了内存使用情况:

echo PHP_EOL;
echo "Memory Usage :".memory_get_usage();
echo PHP_EOL;
echo "Real Memory Usage :".memory_get_usage(true);
echo PHP_EOL;
echo "Real Peak Memory Usage :".memory_get_peak_usage(true);
echo PHP_EOL;
echo "Peak Memory Usage :".memory_get_peak_usage();

最佳答案

要了解问题的答案 - 您需要了解 PHP5 和 PHP7 如何分配内存。

PHP5 假设 Zend Engine 结构“按请求”分配内存。

PHP7 中,它在这方面进行了一些优化,因此在“按 block ”分配内存方面

  • 开始时它分配大块内存
  • 在应用内分配时,它分配小块以避免碎片

这种差异可以很好地提高性能(因为引擎不需要在每次需要时在运行时分配内存并节省一些碎片时间),但它增加了“非常小”程序的内存消耗,它的大小低于“ block 大小”。

是的,PHP7 在大型程序上非常节省内存。

您可以在下面的图片中查看所有这些差异:

使用基准构建的图形: 1.php

<?php

ini_set('memory_limit', '5G');
$a=range(1,$argv[1]);

echo PHP_EOL;
echo "Memory Usage :".memory_get_usage();
echo PHP_EOL;
echo "Real Memory Usage :".memory_get_usage(true);
echo PHP_EOL;
echo "Real Peak Memory Usage :".memory_get_peak_usage(true);
echo PHP_EOL;
echo "Peak Memory Usage :".memory_get_peak_usage();
echo PHP_EOL;

bench.sh

// Small programs
(for i in $(seq 0 5 5000);do php5 dev/Tools/mem/1.php $i|cut -f 2 -d:|sed -r 's/^$/;/g'|sed -r 's/([0-9]+)$/\1,/g'|tr -d '\n'; echo $i; done)|tr -d '\n'|sed -r 's/$/]/g'|sed -r 's/^;/[/g'>php5.m
(for i in $(seq 0 5 5000);do php dev/Tools/mem/1.php $i|cut -f 2 -d:|sed -r 's/^$/;/g'|sed -r 's/([0-9]+)$/\1,/g'|tr -d '\n'; echo $i; done)|tr -d '\n'|sed -r 's/$/]/g'|sed -r 's/^;/[/g'>php7.m
//Large Programs
(for i in $(seq 0 50 100000);do php5 dev/Tools/mem/1.php $i|cut -f 2 -d:|sed -r 's/^$/;/g'|sed -r 's/([0-9]+)$/\1,/g'|tr -d '\n'; echo $i; done)|tr -d '\n'|sed -r 's/$/]/g'|sed -r 's/^;/[/g'>php5.m    
(for i in $(seq 0 50 100000);do php dev/Tools/mem/1.php $i|cut -f 2 -d:|sed -r 's/^$/;/g'|sed -r 's/([0-9]+)$/\1,/g'|tr -d '\n'; echo $i; done)|tr -d '\n'|sed -r 's/$/]/g'|sed -r 's/^;/[/g'>php7.m

Octave 抽屉

php7;php7=ans;
php5;php5=ans;
plot(php5(:,5)',[php5(:,1:4)';php7(:,1:4)']');
legend("PHP5 mgu", "PHP5 rmu", "PHP5 rpmu", "PHP5 pmu","PHP7 mgu", "PHP7 rmu", "PHP7 rpmu", "PHP7 pmu");

阅读更多

  1. 官方 PHP7/PHP-NG 介绍: https://drive.google.com/file/d/0B3UKOMH_4lgBUTdjUGxIZ3l1Ukk/view
  2. 官方 PHP7/PHP-NG 内部变化说明: https://wiki.php.net/phpng-int
  3. 官方扩展程序迁移指南: https://wiki.php.net/phpng-upgrading
  4. 来自@NikiC 的好文章: http://nikic.github.io/2015/05/05/Internal-value-representation-in-PHP-7-part-1.htmlhttp://nikic.github.io/2015/06/19/Internal-value-representation-in-PHP-7-part-2
  5. PHP5 内部细节:http://www.phpinternalsbook.com/
  6. Badoo PHP5->PHP7 成功案例详情:https://techblog.badoo.com/blog/2016/03/14/how-badoo-saved-one-million-dollars-switching-to-php7/

关于php - 与 PHP 5.6 相比,我在 PHP 7 中面临更多的内存消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39740398/

有关php - 与 PHP 5.6 相比,我在 PHP 7 中面临更多的内存消耗的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  3. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  4. ruby-on-rails - HTTParty 的内存问题和下载大文件 - 2

    这会导致Ruby出现内存问题吗?我知道如果大小超过10KB,Open-URI会写入TempFile。但是HTTParty会在写入TempFile之前尝试将整个PDF保存到内存吗?src=Tempfile.new("file.pdf")src.binmodesrc.writeHTTParty.get("large_file.pdf").parsed_response 最佳答案 您可以使用Net::HTTP。参见thedocumentation(特别是标题为“流媒体响应机构”的部分)。这是文档中的示例:uri=URI('http://e

  5. ruby - 我怎样才能更好地了解/了解更多关于 Ruby 的知识? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?

  6. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  7. ruby-on-rails - 内存中具有相同 ID 的更多对象? - 2

    在部署在heroku上的Rails应用程序(v:3.1)中,我在内存中获得了更多具有相同ID的对象。我的heroku控制台日志:>>Project.find_all_by_id(92).size=>2>>ActiveRecord::Base.connection.execute('select*fromprojectswhereid=92').to_a.size=>1这怎么可能?可能是什么问题? 最佳答案 解决方案根据您的SQL查询,您的数据库中显然没有重复条目。也许您的类项目中的size或length方法已被覆盖。我试过find_

  8. ruby - rails 3.0.7 内存泄漏 - 2

    我的两个不同的Rails应用程序的内存有一些奇怪的问题。这两个应用程序都使用rails3.0.7。每个Controller请求分配20-30-50MB的内存。在生产模式下,这个数量减少到5-10。但这是同样的事情。这是两个应用程序使用的gem列表:gem'pg'gem'haml'gem'sass'gem'devise'gem'simple_form'gem'state_machine'gem"globalize3","0.1.0.beta"gem"easy_globalize3_accessors"gem'paperclip'gem'andand'关闭所有这些gem不会给我任何结果。我

  9. ruby - 我在哪里可以找到与其兼容的 Ruby 版本的 gems 版本号? - 2

    这个问题说明了一切。例如,我有一台安装了ruby​​1.8.6的服务器。当我尝试sudogeminstallroo时,它给出了错误nokogirirequiresRubyversion>=1.8.7。所以,我想安装与Ruby1.8.6兼容的旧版本roo。但我不知道去哪里搜索。我知道RubyForge,但它也没有说明Ruby的兼容版本。 最佳答案 蛮力方法是获取一个git克隆,搜索它指定的Ruby版本的位置,然后使用gitblame甚至gitpickaxe来确定最后一个没有的版本'没有那个要求。

  10. ruby - 如何强制 Ruby 释放内存给操作系统 - 2

    正如标题,我有一个处理大量数据的ruby​​程序。该程序占用了所有内存,其中调用了系统命令hostname,并且发生错误无法分配内存-主机名我试过GC.start但它不起作用。那么如何强制ruby释放未使用的内存呢?OK,这是别人的测试代码,最后报错是big_var被回收了。但是内存仍然没有释放。require"weakref"defreportputs"#{param}:\t\tMemory"+`psax-opid,rss|grep-E"^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)[1].to_s+'KB'endbig_var=""#big

随机推荐