2013-09-21 27 views
3

在每篇關於SimpleXML性能和內存使用情況的文章中都提到所有解析的內容都存儲在內存中,處理大文件會導致大量內存使用。 但最近我發現使用SimpleXML處理大文件不會導致大量的內存使用,甚至會導致幾乎沒有內存使用。 有我的測試腳本:PHP SimpleXML大文件沒有額外的內存使用

<?php 
error_reporting(E_ALL); 
ini_set("display_errors", 1); 
print "OS: " . php_uname() . "\n"; 
print "PHP version: " . phpversion() . "\n"; 

print round(memory_get_usage()/1024/1024, 2) . " Mb\n"; 
$large_xml = '<?xml version="1.0" encoding="UTF-8"?><catalog><products>'; 
for ($i = 0; $i < 500000; $i++) { 
    $large_xml .= "<product><id>{$i}</id><name>Product Name {$i}</name><description>Some Description {$i}</description><price>{$i}</price></product>\n"; 
} 
$large_xml .= "</products></catalog>"; 
print round(memory_get_usage()/1024/1024, 2) . " Mb\n"; 
$products_sxml = simplexml_load_string($large_xml); 
print round(memory_get_usage()/1024/1024, 2) . " Mb\n"; 
?> 

我tesing Linux服務器上運行此腳本,PHP版本:5.3.8輸出功率爲:

操作系統:Linux 2.6.32-5-amd64的#1 SMP週一2月25日○時26分11秒UTC 2013 x86_64的

PHP版本:5.3.8

0.6 MB

65.98 MB

65.98 MB

所以我的問題是 - 沒有任何人注意到它,這可能是一個解釋這個,因爲我不能在網絡的任何地方找到它的explanaition - 甚至沒有關於它的確認?

+0

歡迎來到SO。請考慮儘可能簡化您的問題。需要兩三次才能明白你在問什麼。 – dic19

+0

問題是 - 有人可以解釋爲什麼在使用SimpleXML處理大型XML文件時沒有額外的內存使用 - 因爲在每篇關於SimpleXML的文章中都提到大量內存使用是最大的缺點。 – Aigars

回答

4

PHP的內存管理功能非常複雜,準確地測量特定高級代碼的影響是相當困難的。 Julien Pauli在PHP英國會議上進行了很多(非常技術性的)討論,a video of which is available here

爲什麼有memory_get_usage可能是在騙你幾個可能的原因:

  • 首先,memory_get_usage需要的$real_usage一個可選的參數,它分配的內存量和使用量區分 - 內存管理器一次分配一塊內存,所以它通常會比實際使用的內存佔用更多​​的內存。隨着越來越多的需要,已經聲稱的內存已經用完,這意味着不再需要分配。在這種情況下進行測試表明這與此無關。
  • 更一般地說,在運行PHP的底層C代碼中分配內存的方式有很多。由於SimpleXML的大多數工作不是在Zend Engine中完成的,而是在名爲libxml2的第三方庫中完成的,所以內存分配將在那裏完成,而不是在特定於PHP的分配例程中進行,這些例程將在追加時使用到一個PHP字符串。

我從Julien Pauli的幻燈片中看到了以下函數,它查看了Linux內核對正在運行的PHP進程的看法,並找到了代表「Resident Set Size」的行 - 物理內存的數量分配的,而不是量的處理已經要求被保留:

function heap() { 
    return shell_exec(sprintf('grep "VmRSS:" /proc/%s/status', getmypid())); 
} 

添加在您的示例代碼,這個調用(以及爲get_memory_usage(true)),我得到了下面的輸出,顯示的「一顯著分配堆「的內存當您解析XML時:

OS: Linux pink-marmalade 3.8.0-29-generiC#42~precise1-Ubuntu SMP Wed Aug 14 16:19:23 UTC 2013 x86_64 
PHP version: 5.3.10-1ubuntu3.8 
memory_get_usage(): 0.61 Mb 
memory_get_usage(true): 0.75 Mb 
Heap: VmRSS:  6956 kB 

memory_get_usage(): 65.99 Mb 
memory_get_usage(true): 66.25 Mb 
Heap: VmRSS:  74348 kB 

memory_get_usage(): 65.99 Mb 
memory_get_usage(true): 66.25 Mb 
Heap: VmRSS:  761836 kB 
0

如果我執行腳本,我會得到完全相同的結果。 一種解釋可能是您不使用XML對象,因此xml字符串甚至沒有完全解析。 當您修改腳本以便將數據發送到瀏覽器print_r($products_sxml);時,內存使用率在調用後要高得多。 您應該明顯減少xml中的產品數量。

+0

您可以添加XML處理代碼,如 foreach($ products_sxml-> products-> product as $ product_sxml){ \t $ product_count ++; } 並且您將看到內存使用量不會增加。 問題不是關於XML文件大小,而是關於使用SimpleXML處理XML文件的額外內存使用情況。 – Aigars

0

SimpleXML將XML樹存儲在不包含在get_memory_usage函數中的外部資源中。

相關問題