Linux

無法刪除 PHP 腳本的記憶體使用限制

  • November 3, 2012

情況

我遇到了一個 PHP 腳本問題,收到以下錯誤消息:

Fatal error: Out of memory (allocated 359923712) (tried to allocate 72 bytes) in /path/to/piwik/core/DataTable.php on line 969

我正在執行的腳本是:/path/to/piwik/misc/cron/archive.sh

我假設數字是字節,這意味著總數約為 360MB。

出於所有意圖和目的,我已將伺服器上的記憶體限制增加到遠高於 360MB,但這是它始終出錯的數字(給或取一個字節)。

請注意:這個問題不是關於修復腳本中的記憶體洩漏,也不是關於為什麼腳本本身使用這麼多記憶體。該腳本是 Piwik 歸檔過程的一部分,因此我不能只修復任何記憶體洩漏等。有關此腳本的更多資訊以及我增加記憶體限制的原因,請參閱“如何設置自動歸檔”

問題

鑑於腳本試圖使用超過 360MB 的記憶體,而我無法更改,為什麼我似乎無法增加伺服器上 php 的可用記憶體量?

6 月 23 日更新:請參閱下面的“我嘗試過的內容”>“增加 Linux 的每個程序的記憶體限制”以了解背景…如果我設置ulimit -v 1024000了 ,然後檢查它,ulimit -v我得到正確的值 ‘1024000’。如果我再次執行腳本,它會更進一步,但最終會出現錯誤,並達到相同的記憶體限制(~360MB)。如果我立即檢查ulimit -v,它已重置為“524288”的原始值。這似乎是問題的根本原因。


我試過的

增加 PHP 的 memory_limit

給定 php.ini 文件:

php -i | grep php.ini
Configuration File (php.ini) Path => /usr/local/lib
Loaded Configuration File => /usr/local/lib/php.ini

我已經編輯了那個文件,所以 memory_limit 指令讀取;

memory_limit = -1

重啟 Apache,檢查新值是否卡住;

$ php -i | grep memory_limit
memory_limit => -1 => -1

執行腳本,得到同樣的錯誤。

我也嘗試過1G,768M等,都得到相同的結果(即;沒有變化)。

6 月 22 日更新:在Vangel 的幫助下,我嘗試post_max_size結合設置設置為 20M memory_limit。同樣,這沒有效果。

6 月 23 日更新:根據olefebvre 的幫助,我可以確認執行腳本的使用者對包含memory_limit.

移除 Apache 子程序的記憶體限制

我找到並編輯了 httpd.conf 文件以確保沒有RLimitMEM指令。

然後我使用 WHM 的 Apache 配置 > 記憶體使用限制來生成一個限制,它聲稱是 1000M(並通過檢查 httpd.conf 確認)。

這兩種方法都沒有改變 360MB 的腳本錯誤。

增加 Linux 的每個程序的記憶體限制

系統上設置的電流限制:

$ ulimit -m
524288

$ ulimit -v
524288

我試圖將這兩個設置為無限制:

$ ulimit -m unlimited
$ ulimit -v unlimited

$ ulimit -m
unlimited

$ ulimit -v
unlimited

再一次,這導致我的問題完全沒有改善。

6 月 23 日更新:我在這裡遇到了一個相關問題。如果我設置ulimit -v 1024000,然後檢查它,ulimit -v我得到正確的值'1024000’。如果我再次執行腳本,它會更進一步,但最終會出現錯誤,並達到相同的記憶體限制。如果我立即檢查ulimit -v,它已重置為“524288”的原始值。這似乎是問題的根本原因。


我的設置

$ cat /etc/redhat-release
CentOS release 5.5 (Final)

$ uname -a
Linux example.com 2.6.18-164.15.1.el5 #1 SMP Wed Mar 17 11:30:06 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

$ php -i | grep "PHP Version"
PHP Version => 5.2.9

$ httpd -V
Server version: Apache/2.0.63
Server built:   Feb  2 2011 01:25:12
Cpanel::Easy::Apache v3.2.0 rev5291
Server's Module Magic Number: 20020903:13
Server loaded:  APR 0.9.17, APR-UTIL 0.9.15
Compiled using: APR 0.9.17, APR-UTIL 0.9.15
Architecture:   64-bit
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D HTTPD_ROOT="/usr/local/apache"
-D SUEXEC_BIN="/usr/local/apache/bin/suexec"
-D DEFAULT_PIDLOG="logs/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_LOCKFILE="logs/accept.lock"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"

輸出$ php -i: http: //pastebin.com/EiRut6Nm

M. Tibbits 的回答暗示允許 Piwik 在歸檔過程中使用更多資源。

SQL 命令可以執行的大小是有限制的,預設只有 1MB。欲了解更多資訊;數據包太大

要增加 MySQL 中的大小限制,請編輯/etc/my.cnf並設置max_allowed_packet=32M

/usr/local/lib/php.ini通過編輯和設置確保每個分叉程序的 PHP 記憶體限制設置得足夠高memory_limit = 512M

最後,確保所有程序至少有 1G 硬限制,然後系統通過ulimit -v 1048576在命令行上執行將它們關閉。

更新

ulimit -v 1048576只會提高限制。如果限制不夠高,系統會自動將軟限制重置為硬限制。

要設置硬限制,請添加-H開關:

ulimit -vH 1048576

然後將軟限制增加到該值:

ulimit -vS 1048576

背景:

我剛剛獲取了 Piwik 的目前版本——在 1.5 版中,第 969 行顯示為:

public function addRowsFromSerializedArray( $stringSerialized )
{
   $serialized = unserialize($stringSerialized);
   if($serialized === false)
   {
       throw new Exception("The unserialization has failed!");
   }
   $this->addRowsFromArray($serialized);
}

並且是具體的$serialized = unserialize($stringSerialized);。呼叫unserialize可能會佔用大量記憶體。這裡有一個很棒的文章。

正如您所指出的,這顯然不是您腳本中的錯誤,而是有效的 Out of Memory

**建議:**在配置文件中,如上面我的評論中所述:

/.../piwik/config/global.ini.php

我認為您可能需要增加以下限制之一:

# during archiving, Piwik will limit the number of results recorded, for performance reasons
# maximum number of rows for any of the Referers tables (keywords, search engines, campaigns, etc.)
# this limit will also be applied to the Custom Variables names and values reports
datatable_archiving_maximum_rows_referers = 1000
# maximum number of rows for any of the Referers subtable (search engines by keyword, keyword by campaign, etc.)
datatable_archiving_maximum_rows_subtable_referers = 50

# maximum number of rows for any of the Actions tables (pages, downloads, outlinks)
datatable_archiving_maximum_rows_actions = 500
# maximum number of rows for pages in categories (sub pages, when clicking on the + for a page category)
# note: should not exceed the display limit in Piwik_Actions_Controller::ACTIONS_REPORT_ROWS_DISPLAY
#       because each subdirectory doesn't have paging at the bottom, so all data should be displayed if possible.
datatable_archiving_maximum_rows_subtable_actions = 100

# maximum number of rows for other tables (Providers, User settings configurations)
datatable_archiving_maximum_rows_standard = 500

我將分號更改為 # 符號只是為了使 sf 的自動顏色可讀。

您也可以嘗試添加:

CMD_TO_CHECK_SETTINGS="$PHP_BIN -i > /tmp/piwik-php-env.out"
$CMD_TO_CHECK_SETTINGS

到 archive.sh 以確定是否有其他設置正在覆蓋 php.ini 文件。

引用自:https://serverfault.com/questions/280916