當前位置:首頁 » 編程語言 » 內存泄露PHP

內存泄露PHP

發布時間: 2022-09-13 11:16:47

php-fpm子進程會自動重啟嗎

伺服器出現異常,網站不能正常訪問。經排查�php的問題。
在重啟php-fpm時,恢復正常。1分鍾之後又出現故障。查看php日誌文件/usr/local/php/var/log 後提示
WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
子進程數已經達到設置的最大值。
要設置php進程數量。需要在php-fpm.conf文件中修改。
先看/usr/local/php/etc/php-fpm.conf文件各項配置解析
pid = run/php-fpm.pid
#pid設置,默認在安裝目錄中的var/run/php-fpm.pid,建議開啟
error_log = log/php-fpm.log
#錯誤日誌,默認在安裝目錄中的var/log/php-fpm.log
log_level = notice
#錯誤級別. 可用級別為: alert(必須立即處理), error(錯誤情況), warning(警告情況), notice(一般重要信息), debug(調試信息). 默認: notice.
emergency_restart_threshold = 60
emergency_restart_interval = 60s
#表示在emergency_restart_interval所設值內出現SIGSEGV或者SIGBUS錯誤的php-cgi進程數如果超過 emergency_restart_threshold個,php-fpm就會優雅重啟。這兩個選項一般保持默認值。
process_control_timeout = 0
#設置子進程接受主進程復用信號的超時時間. 可用單位: s(秒), m(分), h(小時), 或者 d(天) 默認單位: s(秒). 默認值: 0.
daemonize = yes
#後台執行fpm,默認值為yes,如果為了調試可以改為no。在FPM中,可以使用不同的設置來運行多個進程池。 這些設置可以針對每個進程池單獨設置。
listen = 127.0.0.1:9000
#fpm監聽埠,即nginx中php處理的地址,一般默認值即可。可用格式為: 『ip:port』, 『port』, 『/path/to/unix/socket』. 每個進程池都需要設置.
listen.backlog = -1
#backlog數,-1表示無限制,由操作系統決定,此行注釋掉就行。backlog含義參考:
http://www.3gyou.cc/?p=41
listen.allowed_clients = 127.0.0.1
#允許訪問FastCGI進程的IP,設置any為不限制IP,如果要設置其他主機的nginx也能訪問這台FPM進程,listen處要設置成本地可被訪問的IP。默認值是any。每個地址是用逗號分隔. 如果沒有設置或者為空,則允許任何伺服器請求連接
listen.owner = www
listen.group = www
listen.mode = 0666
#unix socket設置選項,如果使用tcp方式訪問,這里注釋即可。
user = www
group = www
#啟動進程的帳戶和組
pm = dynamic #對於專用伺服器,pm可以設置為static。
#如何控制子進程,選項有static和dynamic。如果選擇static,則由pm.max_children指定固定的子進程數。如果選擇dynamic,則由下開參數決定:
pm.max_children #,子進程最大數
pm.start_servers #,啟動時的進程數
pm.min_spare_servers #,保證空閑進程數最小值,如果空閑進程小於此值,則創建新的子進程
pm.max_spare_servers #,保證空閑進程數最大值,如果空閑進程大於此值,此進行清理
pm.max_requests = 1000
#設置每個子進程重生之前服務的請求數. 對於可能存在內存泄漏的第三方模塊來說是非常有用的. 如果設置為 』0′ 則一直接受請求. 等同於 PHP_FCGI_MAX_REQUESTS 環境變數. 默認值: 0.
pm.status_path = /status
#FPM狀態頁面的網址. 如果沒有設置, 則無法訪問狀態頁面. 默認值: none. munin監控會使用到
ping.path = /ping
#FPM監控頁面的ping網址. 如果沒有設置, 則無法訪問ping頁面. 該頁面用於外部檢測FPM是否存活並且可以響應請求. 請注意必須以斜線開頭 (/)。
ping.response = pong
#用於定義ping請求的返回相應. 返回為 HTTP 200 的 text/plain 格式文本. 默認值: pong.
request_terminate_timeout = 0
#設置單個請求的超時中止時間. 該選項可能會對php.ini設置中的』max_execution_time』因為某些特殊原因沒有中止運行的腳本有用. 設置為 』0′ 表示 『Off』.當經常出現502錯誤時可以嘗試更改此選項。
request_slowlog_timeout = 10s
#當一個請求該設置的超時時間後,就會將對應的PHP調用堆棧信息完整寫入到慢日誌中. 設置為 』0′ 表示 『Off』
slowlog = log/$pool.log.slow
#慢請求的記錄日誌,配合request_slowlog_timeout使用
rlimit_files = 1024
#設置文件打開描述符的rlimit限制. 默認值: 系統定義值默認可打開句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。
rlimit_core = 0
#設置核心rlimit最大限制值. 可用值: 『unlimited』 、0或者正整數. 默認值: 系統定義值.
chroot =
#啟動時的Chroot目錄. 所定義的目錄需要是絕對路徑. 如果沒有設置, 則chroot不被使用.
chdir =
#設置啟動目錄,啟動時會自動Chdir到該目錄. 所定義的目錄需要是絕對路徑. 默認值: 當前目錄,或者/目錄(chroot時)
catch_workers_output = yes
#重定向運行過程中的stdout和stderr到主要的錯誤日誌文件中. 如果沒有設置, stdout 和 stderr 將會根據FastCGI的規則被重定向到 /dev/null . 默認值: 空.
根據以上配置的解析,在php-fpm.conf文件中添加如下配置:
pm.max_children = 100
pm.start_servers = 30
pm.min_spare_servers = 20
pm.max_spare_servers = 100
以觀後效。
另附豆瓣技術貼:https://www.douban.com/note/315222037/
1、php-fpm優化參數介紹
他們分別是:pm、pm.max_children、pm.start_servers、pm.min_spare_servers、pm.max_spare_servers。
pm:表示使用那種方式,有兩個值可以選擇,就是static(靜態)或者dynamic(動態)。
在更老一些的版本中,dynamic被稱作apache-like。這個要注意看配置文件的說明。
下面4個參數的意思分別為:
pm.max_children:靜態方式下開啟的php-fpm進程數量
pm.start_servers:動態方式下的起始php-fpm進程數量
pm.min_spare_servers:動態方式下的最小php-fpm進程數
pm.max_spare_servers:動態方式下的最大php-fpm進程數量
區別:
如果dm設置為 static,那麼其實只有pm.max_children這個參數生效。系統會開啟設置數量的php-fpm進程。
如果dm設置為 dynamic,那麼pm.max_children參數失效,後面3個參數生效。
系統會在php-fpm運行開始 的時候啟動pm.start_servers個php-fpm進程,
然後根據系統的需求動態在pm.min_spare_servers和pm.max_spare_servers之間調整php-fpm進程數
2、伺服器具體配置
對於我們的伺服器,選擇哪種執行方式比較好呢?事實上,跟Apache一樣,運行的PHP程序在執行完成後,或多或少會有內存泄露的問題。
這也是為什麼開始的時候一個php-fpm進程只佔用3M左右內存,運行一段時間後就會上升到20-30M的原因了。
對於內存大的伺服器(比如8G以上)來說,指定靜態的max_children實際上更為妥當,因為這樣不需要進行額外的進程數目控制,會提高效率。
因為頻繁開關php-fpm進程也會有時滯,所以內存夠大的情況下開靜態效果會更好。數量也可以根據 內存/30M 得到,比如8GB內存可以設置為100,
那麼php-fpm耗費的內存就能控制在 2G-3G的樣子。如果內存稍微小點,比如1G,那麼指定靜態的進程數量更加有利於伺服器的穩定。
這樣可以保證php-fpm只獲取夠用的內存,將不多的內存分配給其他應用去使用,會使系統的運行更加暢通。
對於小內存的伺服器來說,比如256M內存的VPS,即使按照一個20M的內存量來算,10個php-cgi進程就將耗掉200M內存,那系統的崩潰就應該很正常了。
因此應該盡量地控制php-fpm進程的數量,大體明確其他應用佔用的內存後,給它指定一個靜態的小數量,會讓系統更加平穩一些。或者使用動態方式,
因為動態方式會結束掉多餘的進程,可以回收釋放一些內存,所以推薦在內存較少的伺服器或VPS上使用。具體最大數量根據 內存/20M 得到。
比如說512M的VPS,建議pm.max_spare_servers設置為20。至於pm.min_spare_servers,則建議根據伺服器的負載情況來設置,比如伺服器上只是部署php環境的話,比較合適的值在5~10之間。
本伺服器配置
1、伺服器基本信息:
硬碟:數據盤30G、系統盤20G
內存:1.5G
CPU:雙核
系統:CentOS 6.3 64位
帶寬:獨享2M
2、部署的應用
Git、SVN、Apache、Tomcat、PHP、Nginx、mysql、JDK
3、優化後的參數
pm = dynamic
pm.start_servers = 5
pm.min_spare_servers = 2
pm.max_spare_servers = 8

② php如何釋放file函數的內存

file函數一般只佔用系統
句柄
資源。讀取其中的內容並保存至某個變數會佔用內存,跟file函數無關。
file函數在打開之後,需要用close關閉並釋放file句柄,否則可能會導致其他程序不能打開這個文件(文件鎖定)。
除了用alloc等函數顯式分配內存的外,一般不需要專門
釋放內存
,系統會在結束時自動回收內存。

③ 什麼是php垃圾回收機制

以下摘自網路:
對象引用計數器機制回收:
php 5.3之前使用的垃圾回收機制是單純的「引用計數」,也就是每個內存對象都分配一個計數器,當內存對象被變數引用時,計數器+1;當變數引用撤掉後,計數器-1;當計數器=0時,表明內存對象沒有被使用,該內存對象則進行銷毀,垃圾回收完成。
「引用計數」存在問題,就是當兩個或多個對象互相引用形成環狀後,內存對象的計數器則不會消減為0;這時候,這一組內存對象已經沒用了,但是不能回收,從而導致內存泄露。
php5.3開始,使用了新的垃圾回收機制,在引用計數基礎上,實現了一種復雜的演算法,來檢測內存對象中引用環的存在,以避免內存泄露。

示例代碼:
class A{
private $b;
function __construct(){
$this->b = new B($this);
}
function __destruct(){
//echo "A destruct\n";
}
function out(){
echo 'oooo',"\n";
}
}

class B{
private $a;
function __construct($a){
$this->a = $a;
}
function __destruct(){
//echo "B descturct\n";
}
}

for($i=0;;$i++){
$a = new A();
if($i00 == 0){
echo memory_get_usage()."\n";
}
}

引起計數器+1的操作:
$a=new A();
$b=&$a;
引起計數器-1的操作:
unset($a);
引起計數器值0對象並釋放內存:
$a=null;
內存相關的函數:
memory_get_usage()返回當前分配給你的 PHP 腳本的內存量,單位是位元組(byte)

memory_get_peak_usage()返回分配給 PHP 內存的峰值
mysql_free_result() 手動釋放mysql結果集內存
gc_enable();//開啟gc自動回收
gc_collect_cycles();//執行一次回收周期
gc_disable();//關閉gc自動回收周期
xdebug_debug_zval(變數名)//載入完xdebug後,可以用這個函數查看變數的狀態
請採納!

④ php是什麼意思

php通常指超文本預處理器,用於面向對象、命令式編程,是一種通用開源腳本語言。

主要特點:

為開源性和免費性、快捷性、資料庫連接的廣泛性、面向過程和面向對象並用。優點是利於學習,使用廣泛。此外,php還可以指菲律賓比索的標准貨幣代碼符號,MPLS網路中的倒數第二跳彈出功能。是英文超級文本預處理語言Hypertext Preprocessor的縮寫。PHP 是一種HTML 內嵌式的語言,是一種在伺服器端執行嵌入HTML文檔的腳本語言,語言風格有些類似於C語言,被廣泛的運用。

簡介:

PHP(外文名:PHP: Hypertext Preprocessor,中文名:「超文本預處理器」)是一種通用開源腳本語言。語法吸收了C語言、Java和Perl的特點,利於學習,使用廣泛,主要適用於Web開發領域。PHP 獨特的語法混合了C、Java、Perl以及PHP自創的語法它可以比CGI或者Perl更快速地執行動態網頁。用PHP做出的動態頁面與其他的編程語言相比,PHP是將程序嵌入到HTML(標准通用標記語言下的一個應用)文檔中去執行,執行效率比完全生成HTML標記的CGI要高許多;PHP還可以執行編譯後代碼,編譯可以達到加密和優化代碼運行,使代碼運行更快。

特性包括:

1、PHP 獨特的語法混合了 C、Java、Perl 以及 PHP 自創新的語法

2、PHP可以比CGI或者Perl更快速的執行動態網頁——動態頁面方面,與其他的編程語言相比,PHP是將程序嵌入到HTML文檔中去執行,執行效率比完全生成htmL標記的CGI要高許多;PHP具有非常強大的功能,所有的CGI的功能PHP都能實現

3、 PHP支持幾乎所有流行的資料庫以及操作系統。

4、最重要的是PHP可以用C、C++進行程序的擴展!

語言特點:

開源免費

PHP是一個受眾大並且擁有眾多開發者的開源軟體項目,linux + Nginx + Mysql + PHP是它的經典安裝部署方式,相關的軟體全部都是開源免費的,所以使用PHP可以節約大量的正版授權費用。不過PHP作為一個開源軟體,它缺乏大型科技公司的支持背景,網路上對它的唱衰也是經久不衰,不過它的持續迭代和性能持續增強的現實卻是鼓舞人心的,PHP社區用實際行動給予各種質疑強有力的回擊。

快捷高效

PHP的內核是C語言編寫的基礎好效率高,可以用C語言開發高性能的擴展組件;PHP的核心包含了數量超過1000的內置函數,功能應有盡有很全面,開箱即用程序代碼簡潔; PHP數組支持動態擴容,支持以數字、字元串或者混合鍵名的關聯數組,能大幅提高開發效率; PHP是一門弱類型語言,程序編譯通過率高,相對其他強類型語言開發效率快;PHP天然熱部署,在php-fpm運行模式下代碼文件覆蓋即完成熱部署;PHP經過20多年的發展,在互聯網上可以搜到海量的參考資料供參考學習。

性能提升

PHP版本越高它的整體性能越高,根據官方介紹,PHP7.0.0 對比PHP5.6性能就提升了2倍,PHP7.4已經比PHP7.0快了約30%,PHP8.0在性能上又相對PHP7.4大約改進了10%。PHP 8.0 引入了 JIT編譯器特性,同時加入多種新的語言功能,例如命名參數、聯合類型、註解、Constructor Property Promotion、match 表達式、nullsafe 運算符以及對類型系統、錯誤處理和一致性的改進。PHP擁有自己的核心開發團隊,保持5年發布一個大版本、1個月發布2個小版本的頻率,最新的版本是PHP8.08 。

跨平台

每個平台都有對應的php解釋器版本,指針對不同平台均編譯出目標平台的二進制碼(PHP解釋器),php開發的程序可以不經修改運行在windows、linux、unix等多個操作系統上。

常駐內存

php-cli模式下可以實現程序常駐內存,各種變數和資料庫連接都能長久保存在內存實現資源復用,比較常用的做法是結合swoole 組件編寫cli框架。

頁面生命周期

在php-fpm模式下,所有的變數都是頁面級的,無論是全局變數還是類的靜態成員,都會在頁面執行完畢後被清空,對程序員水平要求低,佔用內存非常少,特別適合中小型系統的開發。

運行機制:

PHP常見的運行模式有2種,分別是php-fpm 和php-cli 。當PHP 選擇運行在php-fpm模式下,所有的變數都是頁面級的,無論是全局變數還是類的靜態成員,都會在頁面執行完畢後被清空。運行在php-cli模式下可以實現程序常駐內存,各種變數和資料庫連接都能長久保存在內存 實現資源復用,性能可以得到很大的提升,php-cli開發比較復雜能但是能夠獲取更高的性能,對開發者的要求比較高需要比較高的開發水平,比較常用的模式是結合swoole 組件編寫cli框架,各種變數能保存在跨進程的高性能共享內存 Table ,可以開發出支持熱啟動的php-cli可靠各類應用系統。

php-fpm在PHP 5.3.3 版本成為了官方正式組件(2010-07-22),它提供了穩定可靠的進程管理服務,進程不足時候可以智能擴充數量,閑置時候可以自動回收銷毀多餘的進程,同時它對程序的容錯能力很強大運行非常穩定,可以應付企業級的開發需求。php-fpm友好的完成了使用HTTP/HTTPS等TCP/IP互聯網協議下進行的用戶的輸入輸出,頁面級生命周期各種資源用完即釋放,不存在內存泄漏的問題。php-fpm也提供有一些常駐內存的技術支持,例如PHP 7.4引入的opcache.preload也能實現局部的PHP類和函數的常駐內存,不過這個方法不夠靈活,和伺服器配置捆綁的太死了。

php-cli因為能實現各類資源的常駐內存,所以可以資源復用,更高效完成多進程編程和非同步編程,可以開發出負載能力更高的應用系統。但是相對php-fpm的簡單編程開發,開發者要注意很多的事項和需要做很多附加的控制器開發,否則就無法實現期待中的高性能。

首先開發者需要去實現可靠的進程管理服務,保證系統進程遇到各類錯誤退出運行後能夠自動創建新的進程,只有這樣才能保證後續的服務請求有足夠空閑進程可分配。每個業務代碼段都要做異常處理,讓進程遇到非致命錯誤時候不會退出,因為進程重啟意味程序和各類資源需要再次載入,這個過程性能消耗不小,所以只有進程穩定運行了常駐內存才有意義。

其次因為常駐內存,編寫的新的程序必須重啟服務才能生效,這一點習慣了fpm模式的開發者會感到比較陌生。另外開發者需要手工釋放內存,否則系統長時間運行後會出現內存泄露。同時在cli模式下,我們不能像fpm里直接用 $_SERVER、$_POST、$_GET、$_COOKI和$_FILES 進行編程工作,需要自己去解析各種互聯網通訊協議完成用戶的輸入輸出。要實現多進程編程利用多核CPU計算,還有學習使用pcntl和posix編程,這里涉及到了非同步編程邏輯,這塊難度還是比較大的。比較常用的模式是結合swoole 組件編寫cli框架。

PHP是一個活躍的社區開發語言,有專業的核心開發團隊在持續不斷的迭代,最近一個版本就是PHP 8.0.8 引入了很多的新特性。

語言參考:

內置函數

PHP 有很多標準的函數和結構。還有一些函數需要和特定的擴展模塊一起編譯,否則在使用它們的時候就會得到一個致命的「未定義函數」錯誤。例如,要使用 image 函數中的 imagecreatetrue,需要在編譯 PHP 的時候加上 GD 的支持。或者要使用 mysqli_connect函數,就需要在編譯 PHP 的時候加上 MySQLi 支持。有很多核心函數已包含在每個版本的 PHP 中如字元串和變數函數。調用 phpinfo或者 get_loaded_extensions可以得知 PHP 載入了那些擴展庫。同時還應該注意,很多擴展庫默認就是有效的。

靜態網站與動態網站的區別

靜態網站:web1.0 時代

動態網站:web2.0 時代

靜態網站特點:

1、網頁內容一經發布到網站伺服器,無論是否有用戶訪問,每個靜態頁面的內容都是保存在網站伺服器上的。也就是說,靜態網頁是實實在在保存在伺服器上的文件,每個網頁都是一個獨立的文件。

2、靜態網頁的內容相對穩定,因此容易被搜索引擎檢索。

3、 靜態網頁沒有資料庫的支持,在網站製作和維護方面工作量較大,因此當網站信息量很大時完全依靠靜態網頁製作方式比較困難。

4、靜態網頁的交互性較差,在功能方面有較大的限制。


⑤ 怎麼查php代碼內存泄露的問題,有沒有好的解決辦法

沒用的代碼及時摧毀比什麼都有效。

⑥ 關於PHP中 MySQLi擴展庫的問題

首先,指針是指向內存的某一地址的。所以第一個語句是修改該指針指向的地址為0,即NULL。
其次,動態分配內存malloc是在內存的堆上為開辟一塊內存空間。通常會用一個指針來指向該內存,(否則就沒法訪問它了)。free是用來釋放指針所指向的由malloc開辟的內存的。所以free和malloc是成對使用的。
區別就是:一個只是修改了指針的指向,沒有銷毀內存裡面的數據。另一個是銷毀了數據,但是沒有修改指針指向。

如果malloc的內存,直接讓指針賦值NULL,則導致之後無法釋放該內存。進而導致無法再次利用這部分內存,即內存泄露。當然也不能對同一塊內存多次free,那樣也是錯誤的。一般來說,先執行free釋放內存,再賦值為NULL,以避免失誤被再次釋放。

⑦ 內存泄漏是怎麼一回事

一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的,大小任意的(內存塊的大小可以在程序運行期決定),使用完後必須顯示釋放的內存。應用程序一般使用malloc,realloc,new等函數從堆中分配到一塊內存,使用完後,程序必須負責相應的調用free或delete釋放該內存塊,否則,這塊內存就不能被再次使用,我們就說這塊內存泄漏了。
對照這個定義看你的程序,只使用malloc分配內存,而沒有使用free釋放內存,所以出現了內存泄露。
檢測內存泄露的方法可以參考以下兩篇文章:
1、淺談內存泄漏(二),http://www.vczx.com/article/show.php?id=68
2、一個跨平台的 C++ 內存泄漏檢測器,http://www-900.ibm.com/developerWorks/cn/linux/l-mleak2/index.shtml.htm

⑧ swoole 執行過程 內存升高什麼原因

swoole與golang相比有哪些優勢
nodejs有個巨大的問題,就是 JavaScript不是特別適合軟體工程。 你們難道忘記了JavaScript的屬性和原型鏈嘛? 每個對象隨便點一下就添加了一個屬性。 這種哲學會導致內存泄露(或者對象遺忘)非常常見,而且非常容易出現。

phpswoole只能運行在php-cli環境嗎
一直想寫點Swoole的東西,畢竟它重新定義了php,卻一直不知道怎麼下手寫Swoole涉及的知識點非常多,互為表裡,每次想寫都發現根本理不出一個頭緒Swoole是一個php的擴展,它的核心目的就是解決php在實現server服務中可能遇到的一系列問題,這些問...

Swoole比Node.js有哪些優勢?有哪些知名的Swoole案例
nodejs有個巨大的問題,就是 JavaScript不是特別適合軟體工程。 你們難道忘記了JavaScript的屬性和原型鏈嘛? 每個對象隨便點一下就添加了一個屬性。 這種哲學會導致內存泄露(或者對象遺忘)非常常見,而且非常容易出現。

swoole服務層代碼怎麼寫
swoole-1.7.7 發布,內置Http伺服器性能是Node.js的12倍 PHP的非同步並發擴展swoole發布了 1.7.7 版本,此版本主要有: 增加對cygwin環境的支持 增加單次定時器的after介面 onClose事件調整為在close前觸發 增加內置Http伺服器 修復目前已知的所有...

⑨ PHP裡面的include是什麼意思連接資料庫的時候才用嗎後面括弧裡面的以.php為結尾的文件

$usernc是獲取到的用戶輸入信息($_POST['usernc']),trim()去除字元串首尾的無意義的字元(空格、製表符(就是鍵盤上的Tab鍵)、換行符" "(unix及類unix系統的換行符)、回車符" "(又稱軟換行符,Mac OS X的換行符))。(另外說一下,windows的換行符是" ",也支持" ",但不支持單獨的" ")


另外,少用雙引號,單引號更快。
雙引號支持在字元串中嵌入變數,也支持更多的字元轉義(" "," "之類的必須用雙引號)。

例如:

<?php
$b='b';
$str="a{$b}c";//相當於$str='a'.$b.'c';但雙引號更慢
?>

單引號僅支持很少的轉義序列。事實上,它只支持

'''//這是一個單引號字元,相當於"'"

'\'//這是一個反斜線

不過,單引號的速度要快得多。


include可以引入一個PHP文件或HTML文件。

如果引入php文件,那麼php會先執行被include的文件中的代碼,再執行後面的代碼。

如果引入html文件,那麼php會直接輸出這個文件。


在本例中,連接資料庫的代碼被放在了conn文件夾下的conn.php中。

所以,在這里包含此文件,就可以連接到資料庫。


參見PHP手冊:include 和 include_once:

http://php.net/manual/zh/function.include.php

http://php.net/manual/zh/function.include-once.php


舉個例子:

inc.php

<?php
echo'a';
?>

b.php

<?php
echo'm';

//include允許相對路徑與絕對路徑,這里是相對路徑
//PHP手冊推薦在使用include和require時不使用括弧
//因為它們是語法結構(就像if,echo之類的),而不是函數
include'inc.php';
echo'n';
?>

你運行b.php,將會輸出:

man

加不加_once都可以,不過建議你不要加,這樣運行起來會很慢(慢了好幾倍)。

include_once主要是為了防止某些函數被重復定義(多次包含)而報錯。

這應該用合理的代碼規劃來避免,而不是使用_once後綴。

雖然性能問題在小程序中不會得到太大體現,但是在一些復雜的項目中,差勁的代碼導致的性能問題一定會讓你抓狂。


你結合microtime()函數來測試一下,就可以看出來了。

代碼如下:

<?php
//獲取代碼運行的時間
$t=microtime(TRUE);

//這里放上你要測試的代碼

//輸出運行時間,代碼以毫秒為單位
//直接echo很可能會輸出為科學計數法,看起來不直觀
printf('%f',microtime(TRUE)-$t);
unset($t);//變數用完就注銷是個好習慣
?>

另外,如果文件不存在,include會產生警告。

還有一個函數require,與include類似,不過如果文件不存在會產生錯誤。require比include快一些,因為include有返回值,而require沒有。同樣,最好不要使用require_once。


參見PHP手冊:require 和 require_once:

http://php.net/manual/zh/function.require.php

http://php.net/manual/zh/function.require-once.php


另外,我建議您不要再看這本書了,這本書的代碼就好像是一個初學者寫的一樣,根本不符合規范,而且會有很大的性能問題。

例如:

(1)數組鍵名沒有加上引號。php會首先查找是否存在以這個鍵名為名稱的常量。如果存在,這段代碼就很可能會出問題。如果不存在,php沒有辦法,只能返回這個字元串。在這查找的過程中,就會造成相當大的性能損失。

(2)大量使用雙引號,而且還沒有正確利用雙引號的特性。

(3)沒有過濾用戶輸入,存在SQL注入漏洞。應該把單引號轉義。

應該改為:

//適用於大多數資料庫,不適用於Sybase
$usernc=addslashes(trim($_POST['usernc']));
//或者
$usernc=mysql_real_escape_string(trim($_POST['usernc']));//僅適用於MySQL

(4)既然有了$_POST['usernc'],為什麼還要再用$usernc呢?難道就為了少輸幾個字元?浪費伺服器內存資源。伺服器內存資源是非常寶貴的,不應該這樣浪費。每執行一次PHP程序都會創建一個新的操作系統線程,並分配2MB的配套內存。使用不當,可能會造成內存泄露(Out of Memory)!如果是在大型網站上,更應注意此類問題。

(5)既然只是判斷一條數據是否存在(用戶名是否存在),就應該在SQL語句的末尾加上

LIMIT1

否則,會嚴重影響MySQL性能。不加的話,MySQL找到一條數據後,還會繼續查找符合條件的數據(即使並不存在)。如果這個數據表的數據量非常大,那浪費的時間是相當恐怖的!

而加上後,MySQL 搜索到一條數據後就會停止,不會浪費時間。

(6)依賴JavaScript中的history.back()是不對的。如果用戶沒有保存歷史記錄(一些瀏覽器有無痕瀏覽模式,例如Firefox,Chrome等),或者用戶剛好將歷史記錄清除了,這條語句就會失效。最好的辦法是新建一個session變數,例如$_SESSION['history'],將歷史記錄保存在裡面就可以了。再說本例中,程序是應該知道應該跳轉到哪個頁面的(不是有getuserinfo.php嗎?)。

應該直接302重定向。可以使用下面的代碼:

//把「網址」替換為相應的URL就行了
//注意:是從http://一直到URL最後
header('Location:網址');

注意,這之前不能有輸出。或者,在程序最開始的php文件上方加上:

ob_start();

這樣就可以了。


以上這些問題都是應該避免的。

⑩ 如何從log中看到內存泄露問題點

(一) 生成.hprof文件
生成.hprof 文件的方法有很多,而且Android 的不同版本中生成.hprof 的方式也稍有差別,我使用的版本的是2.1,各個版本中生成.prof 文件的方法請參考: http://android.git.kernel.org/?p=platform/dalvik.git;a=blob_plain;f=docs/heapprofiling.html;hb=HEAD。
1. 打開eclipse 並切換到DDMS 透視圖,同時確認Devices、Heap 和logcat 視圖已經打開了;
2. 將手機設備鏈接到電腦,並確保使用「USB 調試」模式鏈接,而不是「Mass Storage「模式;
3. 鏈接成功後在Devices 視圖中就會看到設備的序列號,和設備中正在運行的部分進程;
4. 點擊選中想要分析的應用的進程,在Devices 視圖上方的一行圖標按鈕中,同時選中「Update Heap」和「Dump HPROF file」兩個按鈕;
5. 這是DDMS 工具將會自動生成當前選中進程的.hprof 文件,並將其進行轉換後存放在sdcard 當中,如果你已經安裝了MAT 插件,那麼此時MAT 將會自動被啟用,並開始對.hprof 文件進行分析;
注意:第4 步和第5 步能夠正常使用前提是我們需要有sdcard,並且當前進程有向sdcard中寫入的許可權(WRITE_EXTERNAL_STORAGE),否則.hprof 文件不會被生成,
在logcat 中會顯示諸如 ERROR/dalvikvm(8574): hprof: can't open /sdcard/com.xxx.hprof-hptemp: Permission denied.的信息。
如果我們沒有sdcard,或者當前進程沒有向sdcard 寫入的許可權(如system_process), 那我們可以這樣做:
6. 在當前程序中,例如framework 中某些代碼中,可以使用android.os.Debug 中的: public static void mpHprofData(String fileName) throws IOException 方法,手動的指定.hprof 文件的生成位置。
例如: xxxButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { android.os.Debug.mpHprofData("/data/temp/myapp.hprof"); ... ... } }
上述代碼意圖是希望在xxxButton 被點擊的時候開始抓取內存使用信息,並保存在我們指定的位置:/data/temp/myapp.hprof,這樣就沒有許可權的限制了,而且也無須用sdcard。
但要保證/data/temp 目錄是存在的。這個路徑可以自己定義,當然也可以寫成sdcard 當中的某個路徑。

(二) 使用MAT導入.hprof文件
1. 如果是eclipse 自動生成的.hprof 文件,可以使用MAT 插件直接打開(可能是比較新的ADT才支持);
2. 如果eclipse 自動生成的.hprof 文件不能被MAT 直接打開, 或者是使用android.os.Debug.mpHprofData()方法手動生成的.hprof 文件,則需要將.hprof 文件進行轉換,轉換的方法: 例如我將.hprof 文件拷貝到PC 上的/ANDROID_SDK/tools 目錄下,並輸入命令hprofconv xxx.hprof yyy.hprof,其中xxx.hprof 為原始文件,yyy.hprof 為轉換過後的文件。轉換過後的文件自動放在/ANDROID_SDK/tools 目錄下。OK,到此為止,.hprof 文件處理完畢,可以用來分析內存泄露情況了。
3. 在Eclipse 中點擊Windows->Open Perspective->Other->Memory Analyzer,或者打Memory Analyzer Tool 的RCP。在MAT 中點擊File->Open File,瀏覽並導入剛剛轉換而得到的.hprof文件。

(三) 使用MAT的視圖工具分析內存
導入.hprof 文件以後,MAT 會自動解析並生成報告,點擊Dominator Tree,並按Package分組,選擇自己所定義的Package 類點右鍵,在彈出菜單中選擇List objects->With incoming references。這時會列出所有可疑類,右鍵點擊某一項,並選擇Path to GC Roots -> exclude weak/soft references,會進一步篩選出跟程序相關的所有有內存泄露的類。據此,可以追蹤到代碼中的某一個產生泄露的類。
MAT 的界面如下圖所示。

具體的分析方法在此不做說明了,因為在MAT 的官方網站和客戶端的幫助文檔中有十分詳盡的介紹。 了解MAT 中各個視圖的作用很重要,例如www.eclipse.org/mat/about/screenshots.php 中介紹的。
總之使用MAT 分析內存查找內存泄漏的根本思路,就是找到哪個類的對象的引用沒有被釋放,找到沒有被釋放的原因,也就可以很容易定位代碼中的哪些片段的邏輯有問題了。

另外在測試過程首先需要分析怎麼樣操作一個應用會產生內存泄露然後在不斷的操作中抓取該進程產生的hhprof文件使用MAT工具分析。目前自己的了解查看內存分析內存泄露還有以下幾種方法:

1.使用top命令查看某個進程的內存。例如創建一個腳本文件music.sh 該文件內容為指定程序每隔一秒鍾輸出某個進程的內存使用情況,在此具體實現如下 :
#!/bin/bash
while true; do
adb shell procrank | grep "com.android.music"
sleep 1
done

並且配合使用procank工具可以查看music進程每一秒鍾內存使用情況。

2.另外使用top命令也可是查看內存具體為:
adb shell top -m 10.(查看使用資源最多的10個進程)
adb shell top|grep com.android.music(查看music進程的內存)

3.free命令
free

1.作用free命令用來顯示內存的使用情況,使用許可權是所有用戶。
2.格式free [-b|-k|-m] [-o] [-s delay] [-t] [-V]
3.主要參數-b -k -m:分別以位元組(KB、MB)為單位顯示內存使用情況。
-s delay:顯示每隔多少秒數來顯示一次內存使用情況。
-t:顯示內存總和列。
-o:不顯示緩沖區調節列。
4.應用實例free命令是用來查看內存使用情況的主要命令。和top命令相比,它的優點是使用簡單,並且只佔用很少的系統資源。通過-S參數可以使用free命令不間斷地監視有多少內存在使用,這樣可以把它當作一個方便實時監控器。

#free -b -s5使用這個命令後終端會連續不斷地報告內存使用情況(以位元組為單位),每5秒更新一次。

熱點內容
怎麼把伺服器的ip固定了 發布:2025-01-12 03:55:42 瀏覽:578
php伺服器開發 發布:2025-01-12 03:55:35 瀏覽:672
軟體自製編程 發布:2025-01-12 03:54:00 瀏覽:534
j2ee和java的區別 發布:2025-01-12 03:42:44 瀏覽:581
android6小米 發布:2025-01-12 03:38:35 瀏覽:85
redis與資料庫 發布:2025-01-12 03:20:21 瀏覽:211
怎麼升級安卓100 發布:2025-01-12 03:19:37 瀏覽:516
c語言倒數 發布:2025-01-12 03:14:37 瀏覽:929
如何免費激活行動電話卡安卓 發布:2025-01-12 03:10:27 瀏覽:89
2020凱越精英配置什麼樣 發布:2025-01-12 03:08:02 瀏覽:685