https://github.com/zendtech/php-src/tree/zend-jit/ext/opcache/jit
https://www.phpclasses.org/blog/post/493-php-performance-evolution.html
PHP內置模板引擎,自身就是模板語言.而Java Web須要使用JSP容器如Tomcat或第三方模板引擎.php
PHP內置HTTP服務器和SQLite數據庫,以及Apache模塊實現libphp.so和FastCGI服務PHP-FPM.而Java Web開發時廣泛須要使用第三方的Servlet容器Tomcat等.PHP內置的單進程HTTP服務器(可用於快速開發和測試):
php -S 127.0.0.1:8080 -t /www
nginx.conf: 訪問io.php的請求都交給監聽9001的PHP-FPM進程池處理
location = /io.php {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9001;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
php-fpm: 正常腳本由靜態www池處理,阻塞腳本由動態io池處理
[www]
;名爲www的進程池監聽9000端口,常駐進程數量爲固定4個
listen = 127.0.0.1:9000
pm = static
pm.max_children = 4
[io]
;名爲io的進程池監聽9001端口,進程數常駐4個,最大8個
listen = 127.0.0.1:9001
pm = dynamic
pm.max_children = 8
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 4
其中I/O密集這個進程池[io]採用動態的prefork進程,好比這裏是繁忙時8個,空閒時4個.
利用PHP-FPM提供的池的隔離性,分離計算密集和I/O密集操做,能夠減小阻塞對整個PHP應用的影響.
也就是說,PHP經過多進程利用多核實現併發,而Java廣泛經過多線程實現併發,由於一個JVM實例就是一個進程.html
另外,PHP也能夠運行在多線程模式下,好比Apache的event MPM和Facebook的HHVM都是多線程架構.不論是多進程仍是多線程的PHP Web運行模式,都不須要PHP開發者關心和控制,也就是說PHP開發者不須要寫代碼參與進程和線程的管理,這些都由PHP-FPM/HHVM/Apache實現.java
PHP-FPM進程管理和併發實現並不須要PHP開發者關心,而Java多線程編程須要Java開發者編碼參與.PHP一個worker進程崩潰,master進程會自動新建一個新的worker進程,並不會致使PHP服務崩潰.而Java多線程編程稍有不慎(好比沒有捕獲異常)就會致使JVM崩潰退出.mysql
對於PHP-FPM和Apache MOD_PHP來講,服務進程常駐內存,但一次請求釋放一次資源,這種內存釋放很是完全. PHP基於引用計數的GC甚至都還沒發揮做用程序就已經結束了. 並且,在PHP腳本中用unset顯式釋放內存也是立竿見影的,不會有延時.而Java的內存回收嚴重依賴GC機制,高併發下的Full GC會致使Java服務雪崩:JVM忙於用GC回收內存沒法處理請求,而新請求又源源不斷地到來.nginx
PHP的運行模式決定了PHP自然支持熱部署,而Java要實現熱部署並不容易.這也是爲何在虛擬主機託管環境裏PHP佔絕對優點的緣由,由於開發者經過FTP上傳PHP文件到虛擬空間就實現了代碼更新和部署.git
PHP跨進程共享數據,除了使用基於文件的session機制和鳥哥開發的無鎖共享內存緩存擴展Yac.Linux上還可使用內存文件系統(tmpfs)上的SQLite(如/dev/shm/data.sqlite3).而Java程序的生命週期隨JVM常駐內存,線程能夠訪問共享數據.github
PHP不存在數據庫訪問速度比Java慢的問題.PHP的數據庫驅動如mysqlnd等都是C實現的驅動,而Java的數據庫驅動JDBC是Java實現的驅動,PHP的驅動性能並不吃虧.並且PHP一樣支持數據庫持久鏈接,也就是多個請求能複用一個數據庫鏈接,並不須要每一個請求都打開一個數據庫鏈接.好比下圖就是兩個PHP-FPM工做進程跟MySQL保持的兩個長鏈接:sql
C實現的PHP後來吸取了C++的對象編程思想,加入了對象編程支持.既能夠用過程式,也能夠用對象,更靈活.而Java必須徹底面向對象編程,甚至還要把類名和文件名掛鉤.數據庫
PHP能不能開發大型應用,取決於使用者是否因地制宜地使用PHP. 好比,PHP就不適合用來開發數據庫引擎(大多都是C/C++實現)等計算密集型應用.Java在計算密集型應用上相比PHP更有優點,好比HBase數據庫使用了Java實現.不過大多數Web應用都是I/O密集型應用,這裏麪包括網絡I/O,文件系統I/O,數據庫I/O.apache
PHP是C實現的Web快速開發框架,不依賴第三方框架也能實現快速開發.而Java Web開發廣泛依賴Spring等第三方框架.
補充:
回覆
數據庫持久鏈接很容易用,mysqli裏host參數傳遞p:127.0.0.1就能開啓持久鏈接,pdo_mysql裏把PDO::ATTR_PERSISTENT設爲true也能夠開啓持久鏈接.並且PHP的數據庫持久鏈接也不依賴PHP-FPM,個人截圖不過是舉例說明,其實用Apache也同樣能夠.只是PHP-FPM的進程數或者Apache進程/線程數最好配置爲固定數量,並且要求數量不能超過MySQL最大鏈接數(max_connections默認是151).
進程間共享數據,除了Yac,我不是還說了Linux內存文件系統tmpfs上的SQLite麼?SQLite的鎖機制夠用了呀,連事務都支持,你擔憂什麼?並且內存上也不須要擔憂SQLite的讀寫性能限制,徹底是SQLite引擎在內存上的計算密集操做.能利用Linux的tmpfs機制,能利用SQLite的鎖機制,而不依賴PHP實現,我以爲頗有優點很穩定.
這裏討論的不是Swoole這類CLI下實現的PHP服務,而是PHP傳統的FastCGI模式.長時間後臺常駐運行的PHP腳本,固然須要GC.對於一些要求實時的高併發應用,我以爲就不該該使用GC機制.PHP能夠配置zend.enable_gc=off來禁用GC,而且本身經過unset來手動釋放內存.不過運行在FastCGI下的PHP腳本生命週期很短,其實原本就不依賴GC.再次強調,高併發實時類應用,GC毫不是一個優點,而是一個劣勢.
PHP常見的SAPI有這麼幾種:
php(cli,cli-server)
php-cgi(cgi-fcgi)
php-fpm/hhvm(fpm-fcgi)
libphp7.so/php7apache2_4.dll(apache2handler)
fpm-fcgi和apache2handler下,不管是多進程模式仍是多線程模式,進程和線程的實現和管理都不須要PHP開發者關心(這是優點),而是由php-fpm/hhvm/apache實現.PHP開發者若是要參與多進程或多線程編程,徹底能夠在php-cli下實現,相關PECL擴展包括pcntl多進程,pthreads多線程,libevent事件驅動等等,相關的項目實現有WorkerMan.另外峯哥的Swoole也須要用php-cli跑,但其服務的進程和線程控制也是由Swoole實現而不太須要PHP開發者關心.
PHP從5.4內置的單進程HTTP服務器,目的就是用於快速的開發和測試,我以爲是一個很方便的工具,開發者不須要安裝和配置Apache或者Nginx之類Web服務器就能進行入門開發.並且把PHP解釋器交叉編譯到Android手機或者OpenWRT無線路由就能用PHP這個省資源的HTTP服務器在局域網內編程並提供服務,很方便.
JIT在大量計算上有優點,bench.php腳本就是用來測試計算性能.真實應用如WordPress等,JIT能帶來的性能提高確定不會這麼明顯,具備JIT機制的HHVM和沒有JIT的PHP7,在壓力測試WordPress時體現出同一水平,就說明了這個問題.並且我強調過,Web應用大可能是I/O密集型應用,編譯型語言不會在I/O密集型應用裏也具備數量級的優點.因此說,對於大多數PHP開發者來講,就算是沒有JIT機制的PHP7,性能也夠用了.
回覆mem php-fpm && siege -c10 -t1M http://www.example.com/app/punbb/index.php > /dev/null && mem php-fpm
其中mem是我定義在~/.bashrc裏的一個用於快速根據名稱查看程序狀況的函數:
mem ()
{
top -n1 -b | head -n7 | sed '1,6d' && top -n1 -b | sed '1,7d' | grep --color=auto -i $1;
ps aux | grep --color=auto -i $1 | grep --color=auto -v grep | awk -F " " '{ sum += $6 } END { printf "Total Memory Usage: %.1f MB\n", sum/1024 }'
}
鄙人工做須要,兩種語言不斷切換,就簡單談一談二者區別
首先php確實是開發速度極快,爲何?由於弱類型(php7有類型聲明選擇開關,只要引入開關指令declare(strict_type=1)就會強制當前的文件下的程序遵循嚴格的參數類型,返回值類型),不須要定義返回的類型,加上php實際開發過程當中喜歡運用它萬能的數組來作計算,返回。因此他的動態擴展性很是強,若是返回值結構改變,不要緊,直接改數組結構就行(注意,php數組太強大,能夠看成map,list來用,底層的實現實際上是hashmap) 而java可能要開發過程可能要慢一點,java面向對象的技巧,設計模式會運用的更多一點。須要定義各種model來適應你業務的需求。編寫風格會有必定的統一要求。強類型在編寫的時候會比php麻煩,但好處是更安全,由於類型固定,潛在風險較低,還有編譯器給你作了一次保障。