【问题标题】:How does apache PHP memory usage really work? [closed]apache PHP 内存使用如何真正起作用? [关闭]
【发布时间】:2012-07-13 09:23:19
【问题描述】:

给出一些上下文:

我最近和一位同事讨论了在 PHP 中使用 Autoloaders。我支持他们,他反对。

我的观点是,自动加载器可以帮助您最大限度地减少手动源依赖,从而帮助您减少在包含大量您可能不需要的大文件时消耗的内存量。

他的回答是,包含您不需要的文件并不是什么大问题,因为一旦文件被包含在 Apache 子进程的内存中,这部分内存将可用于后续请求。他认为您不应该担心包含文件的数量,因为它们很快就会全部加载到内存中并按需从内存中使用。因此,内存不是问题,而在文件系统上尝试查找所需文件的开销则更令人担忧。

他是个聪明人,而且往往知道自己在说什么。但是,我一直认为 Apache 和 PHP 使用的内存是特定于正在处理的特定请求的。 每个请求都分配了等于 memory_limit PHP 选项的内存量,并且任何源代码编译和处理仅在请求的生命周期内有效。

即使使用 APC 等操作码缓存,我认为单个请求仍需要将每个文件加载到它自己的内存部分中,并且 APC 只是为响应进程预编译它的捷径。

我一直在搜索这方面的一些文档,但到目前为止还没有找到任何东西。如果有人能指出有关此主题的任何有用文档,我将不胜感激。

更新:

澄清一下,自动加载器讨论部分更多的是上下文:)。

可能还不清楚,但我的主要问题是关于 Apache 是否会将其资源集中起来以响应多个请求(尤其是包含文件使用的内存),或者每个请求是否需要检索满足执行路径与从同一进程处理的其他请求隔离。

例如: 文件 1、2、3 和 4 大小相同,均为 100KB。 请求 A 包括文件 1、2 和 3。 请求 B 包括文件 1、2、3 和 4。

在他的脑海中,他认为请求 A 在整个执行过程中会消耗 300KB,而请求 B 只会再消耗 100KB,因为文件 1,2 和 3 已经在内存中。

在我看来,它是 300KB 和 400KB,因为它们都是独立处理的(如果通过相同的进程)。

这让他回到了他的论点,即“只包括很多,因为无论如何你都会使用它”,而不是我的“只包括你需要减少请求大小的东西”。

这对于我如何构建 PHP 网站来说是相当基础的,所以我很想知道我是否在这里偏离了目标。

我也一直相信,对于大型网站来说,内存是最宝贵的资源,而且比文件系统检查可能被内核缓存的自动加载器更值得关注。

你是对的,是时候进行基准测试了!

【问题讨论】:

    标签: php memory process apache2


    【解决方案1】:

    以下是赢得争论的方法:运行现实的基准测试,并站在数字的右边。

    我也有过同样的讨论,所以我尝试了一个实验。使用 APC,我尝试了一个带有单个整体包含(包含所有 Kohana)以及标准自动加载器的 Kohana 应用程序。最终结果是,单个包含以统计上不相关的速率(小于 1%)更快,但使用的内存略多(根据 PHP 的内存函数)。在没有 APC(或 XCache 等)的情况下运行测试是没有意义的,所以我没有打扰。

    所以我的结论是继续使用自动加载,因为它使用起来更简单。在您的应用中尝试相同的操作,并向您的朋友展示结果。

    现在你不需要猜测了。

    免责声明:我没有使用 Apache。我不能强调在自己的应用程序上在自己的硬件上运行自己的基准测试。不要相信我的经历会是你的。

    【讨论】:

    • 谢谢 Matthew,我已经对原始帖子进行了编辑以防万一,但我肯定会进行一些测试!
    • 我不确定 mod_php 如何处理为同一页面提供服务,但如果您使用操作码缓存,那么 PHP 文件本身肯定会在共享内存中。我理解普通 PHP 的方式是,在每次请求时,文件都会被打开、解析和执行……所以我不确定内存共享会发生在哪里。我认为它仍然归结为基准测试......使用ab 之类的东西来运行测试。我相信您会看到,是否使用自动加载取决于个人喜好......我认为性能不会有显着差异。
    【解决方案2】:

    你是更聪明的忍者,蚱蜢。

    在请求类之前,自动加载器不会加载类文件。这意味着它们最多会使用与手动包含的内存量相同的内存量,但通常要少得多。

    即使 apache 线程可以处理多个请求,每个请求也会从文件中重新读取类,因此您的朋友“最终都被读取”是站不住脚的。

    您可以通过添加 echo 'foo' 来证明这一点;在类文件中的类定义之上。无论您是在开始时自动加载还是手动包含整个类文件,您都会在每个新请求中看到该行将被执行。

    我在这方面找不到任何好的简明文档——我可能会写一些带有一些内存使用示例的文档——因为我还必须向其他人解释这一点并出示证据以使其深入了解。我认为Zend 的人认为没有人会看到自动加载的好处。

    是的,apc 之类的(像所有缓存解决方案一样)可以克服资源的负面影响,甚至可以在性能上获得小幅提升,但是如果您在大量库和服务上执行此操作,则会消耗大量不需要的内存大量的客户。尝试一些事情,比如在一个庞大的包含文件中加载一个健康的梨库块,同时处理 500 个连接到您的页面。

    即使使用 Apc 之类的东西,您也可以从对任何非命名空间类(目前大多数现有的 php 代码)使用自动加载器中受益,因为它可以在处理大量类库时帮助避免全局命名空间污染。

    【讨论】:

      【解决方案3】:

      这是我的意见。

      我认为自动加载器是一个非常糟糕的主意,原因如下

      1. 我想知道我的脚本从什么地方以及从哪里获取数据/代码。使调试更容易。
      2. 如果您的一位开发人员更改了文件(升级等)或配置并且事情停止工作,那么这也存在配置问题,因此更难找出问题所在。
      3. 我也觉得是懒惰编程。

      至于内存/性能问题,如果计算机遇到困难,为计算机购买更多内存同样便宜。

      【讨论】:

      • 您能否详细说明为什么您认为这是惰性编程?我很好奇,因为拥有自动加载功能似乎很合理。
      • @Dave - 我认为不明确说明您的脚本的组成部分并依靠解释器来找到合适的代码是很懒惰的。它还有助于文档和未来的维护。为什么输入require 这么费劲?
      • @Ed 可以说,在所有条件相同的情况下,懒惰的程序员比一直在努力工作的程序员要好
      • Ed 您的回答来自文体方法而不是效率。我会说我个人不同意你的推理: 1. 大多数自动加载器用户通过一个约定来操作,这使得你的代码来自哪里非常非常明显。大多数现代 IDE 也可以轻松跳转到正确的文件以读取/调试您的代码。 2. 一样,我没看到。 3. 如果你以一种合理的方式设计你的代码库,这样你就可以期望每个类/文件对每个需要它的脚本都是可用的,我个人不会认为这很懒。
      • 它是否好只是一种意见(如您所说)。它是否表现更好是可以测试的事实。 Sirhara 的问题是关于后者。无论如何,从主观角度衡量,根据我的经验,避免自动加载的最大负面影响是人们倾向于避免编写设计良好的面向对象的代码,因为他们厌倦了指定数十个包含。但我不反对手动包含,特别是如果我通过线路获得报酬。 ;)
      猜你喜欢
      • 2017-08-20
      • 2017-07-30
      • 1970-01-01
      • 1970-01-01
      • 2018-03-23
      • 2018-09-01
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      相关资源
      最近更新 更多