Java虛擬機6:內存溢出和內存泄露、並行和併發、Minor GC和Full GC、Client模式和Server模式的區別

前言java

以前的文章尤爲是講解GC的時候提到了不少的概念,好比內存溢出和內存泄露、並行與併發、Client模式和Server模式、Minor GC和Full GC,本文詳細講解下這些概念的區別。編程

 

內存溢出和內存泄露的區別服務器

一、內存溢出併發

內存溢出指的是程序在申請內存的時候,沒有足夠大的空間能夠分配了。jvm

二、內存泄露編輯器

內存泄露指的是程序在申請內存以後,沒有辦法釋放掉已經申請到內存,它始終佔用着內存,即被分配的對象可達但無用。內存泄露通常都是由於內存中有一塊很大的對象,可是沒法釋放。工具

從定義上能夠看出,內存泄露終將致使內存溢出。性能

注意,定位虛擬機問題內存問題的時候第一步就是要判斷究竟是內存溢出仍是內存泄露,前者好判斷,跟蹤堆棧信息就能夠了;後者比較複雜一點,通常都是老年代中的大對象沒釋放掉,要經過各類辦法找出老年代中的大對象沒有被釋放的緣由。優化

 

並行和併發的區別spa

這兩個名詞都是併發編程中的概念,在談論垃圾收集器的上下文語境中,能夠這麼理解這兩個名詞:

一、並行Parallel

多條垃圾收集線程並行工做,但此時用戶線程仍然處於等待狀態

二、併發Concurrent

指用戶線程與垃圾收集線程同時執行(但並不必定是並行的,可能會交替執行),用戶程序在繼續運行,而垃圾收集程序運行於另外一個CPU上

 

Minor GC和Full GC的區別

一、新生代GC(Minor GC)

指發生在新生代的垃圾收集動做,由於大多數Java對象存活率都不高,因此Minor GC很是頻繁,通常回收速度也比較快

二、老年代GC(Major GC/Full GC)

指發生在老年代的垃圾收集動做,出現了Major GC,常常會伴隨至少一次的Minor GC(但並非絕對的)。Major GC的速度通常要比Minor GC慢上10倍以上

 

Client模式和Server模式的區別

部分商用虛擬機中,Java程序最初是經過解釋器對.class文件進行解釋執行的,當虛擬機發現某個方法或代碼塊運行地特別頻繁的時候,就會把這些代碼認定爲熱點代碼Hot Spot Code(這也是咱們使用的虛擬機HotSpot名稱的由來)。爲了提升熱點代碼的執行效率,在運行時,虛擬機將會把這些代碼編譯成與本地平臺相關的機器碼,並進行各類層次的優化,完成這個任務的編譯器叫作即時編譯器(Just In Time Compiler,即JIT編譯器)。JIT編譯器並非虛擬機必需的部分,Java虛擬機規範並無要求要有JIT編譯器的存在,更沒有限定或指導JIT編譯器應該如何去實現。可是,JIT編譯器性能的好壞、代碼優化程度的高低倒是衡量一款商用虛擬機優秀與否的最關鍵指標之一。

解釋器和編譯器其實和編譯器各有優點:

一、當程序須要迅速啓動和執行的時候,解釋器能夠先發揮做用,省去編譯的時間,當即執行

二、在程序運行後,隨着時間的推移,編譯器逐漸發揮做用,把愈來愈多的代碼編譯成本地代碼以後,能夠獲取更高的執行效率

咱們使用的HotSpot中內置了兩個JIT編譯器,即C1編譯器和C2編譯器,默認採用的是解釋器和一個編輯器配合的方式進行工做。HotSpot在啓動的時候會根據自身版本以及宿主機器的硬件性能自動選擇運行模式,好比會檢測宿主機器是否爲服務器、好比J2SE會檢測主機是否有至少2個CPU和至少2GB的內存。

一、若是是,則虛擬機會以Server模式運行,該模式與C2編譯器共同運行,更注重編譯的質量,啓動速度慢,可是運行效率高,適合用在服務器環境下,針對生產環境進行了優化

二、若是不是,則虛擬機會以Client模式運行,該模式與C1編譯器共同運行,更注重編譯的速度,啓動速度快,更適合用在客戶端的版本下,針對GUI進行了優化

有兩種方法查看虛擬機是運行在Client模式下仍是Server模式下:

一、在程序命令行運行「java -version」命令,查看的是你本地安裝的虛擬機是信息

二、好比咱們用Eclipse或者MyEclipse運行程序,通常使用的都是工具自帶的JRE,虛擬機並非本地安裝的虛擬機。這時候怎麼辦呢,能夠經過在程序中運行下面的語句來查看虛擬機信息

System.out.println(System.getProperty("java.vm.name"));

我這裏的運行結果是

Java HotSpot(TM) 64-Bit Server VM

固然要改變虛擬機運行的模式也能夠,只須要改jvm.cfg就能夠了。咱們能夠從如下幾個地方找到jvm.cfg:

一、32位的JDK的文件路徑是  JAVA_HOME/jre/lib/i386/jvm.cfg

二、64位的JDK的文件路徑是  JAVA_HOME/jre/lib/amd64/jvm.cfg

三、MyEclipse在 .../Common/binary/com.sun.java.jdk.win32.x86_64_1.6.0.013/jre/lib/amd64/jvm.cfg

目前64位只支持Server模式,文件內容都是同樣的,上面的註釋不去管它,剩下的就是這些:

-server KNOWN
-client IGNORE
-hotspot ALIASED_TO -server
-classic WARN
-native ERROR
-green ERROR

因爲個人電腦裝的是64位JDK,因此是「-client INGORE」。同時支持Server模式和Client模式的,應該是「-server KNOWN」和「-client KNOWN」,通常只須要變動這兩個配置的前後順序便可,可是前提是JAVA_HOME/jre/bin目錄下同時存在server和client兩個文件夾,分別對應着各自的虛擬機,缺乏一個,切換後就會報錯。

相關文章
相關標籤/搜索