草庐IT

php - 解决 PHP 内存泄漏

coder 2023-10-12 原文

我有一个无限长运行的 PHP 脚本(无限主事件循环)处理来自 Twitter 的传入推文流并将它们存储到 MySQL。但是,我似乎无法控制它的内存使用情况。我发现了 3 种测量内存使用情况的方法:

  • memory_get_usage() - 报告大约 4.0 MB
  • memory_get_usage(true) - 报告大约 7.5 MB
  • exec("ps -o rss -p ".getmypid(), $memOutput); - 报告一个线性增加的数字,该数字在 60 分钟或更短时间内迅速增长到数百 MB,并且继续消耗内存,直到脚本被强制终止。

我的问题:

1) 这三种措施之间的实际区别是什么?

但主要是:

2) 如果前两个相对恒定,但第三个方法像这样疯狂失控,这意味着什么?

FWIW,我正在使用 PHP 5.3 和 Zend Framework 1.x 以及大量 Zend_Db 事件。脚本在 CLI SAPI 下运行。 Zend_Db_Profiler 没有被使用。我还有第二个无限运行的脚本,它根本不使用数据库,并且内存使用量是恒定的。所以它似乎与数据库有关,也许是我的 PHP 设置正在使用的 MySQL 扩展,或者可能是 Zend_Db。我在自己的代码中煞费苦心地避免粗心大意地缓存对象,尽管我还没有对 Zend 的代码本身这样做。

我已经尝试让我的脚本调用 gc_enable(),并定期运行 gc_collect_cycles(),但这没有帮助。

有什么想法吗?

编辑 我打算尽快分析这段代码,但与此同时我注意到即使我不接触数据库的脚本也在泄漏内存。但它们这样做的速度要慢得多,只有在比较几天的内存使用情况时才会变得明显。

最佳答案

好吧,我无法在这里为您指出确切的答案,因为您需要自己进行分析。从你所说的来看,它似乎指向 Zend 的 DB 层,但是除非你对此进行分析,否则你无法确定。 ;)

在 UNIX/Linux 上(我希望您以正确的方式运行 PHP - UNIX/Linux 方式:D)有一些非常有用的工具可用于在系统级别 分析此类应用程序并检查PHP 应用程序中的实例化和内存消耗。 您可以使用 Valgrind获取一些信息,例如:

valgrind --tool=callgrind --dump-instr=yes -v --instr-atstart=no /usr/sbin/apache2 -X

注意 Valgrind 是一个 suite of tools在这里我们使用“callgrind”工具 - 它

provides all the information that Cachegrind does, plus extra information about callgraphs

这将创建一个 callgrind.out 文件或一组我不记得的文件。 无论如何,您现在可以使用 Kcachegrind可视化收集的信息:

kcachegrind callgrind.out

您将看不到调用的可视化以及应用程序特定部分使用的内存百分比。就像是:

您还可以尝试 Valgrind 套件中的其他一些工具,例如 Memcheck

all reads and writes of memory and calls to malloc/new/free/delete

我第一次了解 Valgrind 是在尝试分析我的 Linux 服务器时。然后我研究了一下,结果发现它是一个非常好的分析 PHP 应用程序的工具......有 a very good talk on this here .我使用了那里的一些例子。检查一下!

在您介绍您的应用程序之后,请返回有关它是什么的信息,或者您看到了什么等等。我将很乐意对此进行分析。希望这有所帮助。 ;)

编辑: 我现在想起来我错过了一些东西。 :D 您也可以尝试使用 APD这是一个 zend 扩展和 could also provide useful information .我没有亲自使用过它,但互联网上有一些很好的例子。

另一个选项是 Xhprof - 层次分析器。你可以用它来 gather different metrics .最后应该结合使用这些工具。如何以及为什么取决于您。

关于php - 解决 PHP 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18524984/

有关php - 解决 PHP 内存泄漏的更多相关文章

  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. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  4. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  5. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  6. 键删除后 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

  7. ruby - 如何更快地解决 project euler #21? - 2

    原始问题Letd(n)bedefinedasthesumofproperdivisorsofn(numberslessthannwhichdivideevenlyinton).Ifd(a)=bandd(b)=a,whereab,thenaandbareanamicablepairandeachofaandbarecalledamicablenumbers.Forexample,theproperdivisorsof220are1,2,4,5,10,11,20,22,44,55and110;therefored(220)=284.Theproperdivisorsof284are1,2,

  8. 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

  9. ruby - 为什么这些方法没有解决? - 2

    这个问题在这里已经有了答案:WhydoRubysettersneed"self."qualificationwithintheclass?(3个答案)关闭29天前。给定这段代码:classSomethingattr_accessor:my_variabledefinitialize@my_variable=0enddeffoomy_variable=my_variable+3endends=Something.news.foo我收到这个错误:test.rb:9:in`foo':undefinedmethod`+'fornil:NilClass(NoMethodError)fromtes

  10. 电脑启动后显示器黑屏怎么办?排查下面4个问题,快速解决 - 2

    电脑启动出现显示器黑屏是一个相当常见的问题。如果您遇到了这个问题,不要惊慌,因为它有很多可能的原因,可以采取一些简单的措施来解决它。在本文中,小编将介绍下面4种常见的电脑启动后显示器黑屏的原因,排查这些原因,快速解决! 演示机型:联想Ideapad700-15ISK-ISE系统版本:Windows10一、显示器问题如果出现电脑启动后显示器黑屏的情况。那么首先您需要检查一下显示器是否正常工作。您可以通过更换另一个显示器或将当前显示器连接到另一台计算机来检查显示器是否存在问题。如果问题仍然存在,那么您可以排除显示器故障的可能性。 二、显卡问题如果您的电脑配备了独立显卡,那么显卡故障也可能是导致电脑

随机推荐