国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

學(xué)習(xí)筆記:Java的一些基礎(chǔ)小知識(shí)之JVM與GC

2019-11-14 22:53:48
字體:
供稿:網(wǎng)友
學(xué)習(xí)筆記:java的一些基礎(chǔ)小知識(shí)之JVM與GC一、JVM是什么
Java虛擬機(jī)(英語:Java Virtual Machine,縮寫為JVM),又名爪哇虛擬器,一種能夠運(yùn)行Java bytecode的虛擬機(jī),以堆棧結(jié)構(gòu)機(jī)器來進(jìn)行實(shí)做。最早由太陽微系統(tǒng)所研發(fā)并實(shí)現(xiàn)第一個(gè)實(shí)現(xiàn)版本,是Java平臺(tái)的一部份,能夠運(yùn)行以Java語言寫作的軟件程序。Java虛擬機(jī)有自己完善的硬體架構(gòu),如處理器、堆棧、寄存器等,還具有相應(yīng)的指令系統(tǒng)。JVM屏蔽了與具體操作系統(tǒng)平臺(tái)相關(guān)的信息,使得Java程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。通過對(duì)中央處理器(CPU)所執(zhí)行的軟件實(shí)作,實(shí)現(xiàn)能執(zhí)行編譯過的Java程序碼(Applet與應(yīng)用程序)。作為一種編程語言的虛擬機(jī),實(shí)際上不只是專用于Java語言,只要生成的編譯文件符合JVM對(duì)載入編譯文件格式要求,任何語言都可以由JVM編譯運(yùn)行。除外,除了甲骨文,也有其他開源或閉源的實(shí)現(xiàn)。——維基百科
這個(gè)描述還是很簡單易懂的,虛擬機(jī)的這種機(jī)制帶給了代碼一種全新的生命力,就是一處編繹,到處運(yùn)行。當(dāng)然美好的事情總歸是有些缺陷的。因?yàn)橐谝慌_(tái)物理機(jī)器上搭建一套虛擬的體系,以此來解決各個(gè)硬件與系統(tǒng)間的差異問題,確實(shí)是件很美好的事情,但同時(shí)損失的自然就是運(yùn)行時(shí)的效率。二、JVM的體系規(guī)格java的這套體系是種開放的規(guī)格,只要能按規(guī)格編繹出來的程序都可以跑在JVM上。JVM定義了控制Java代碼解釋執(zhí)行和具體實(shí)現(xiàn)的五種規(guī)格,它們是:
  • JVM指令系統(tǒng)
  • JVM寄存器
  • JVM 棧結(jié)構(gòu)
  • JVM 碎片回收堆
  • JVM 存儲(chǔ)區(qū)
三、JVM的工作原理
  • 操作系統(tǒng)加載JVM(windows)
1.創(chuàng)建JVM裝載環(huán)境和配置2.裝載JVM.dll3.初始化JVM.dll并掛界到JNIENV(JNI調(diào)用接口)實(shí)例4.調(diào)用JNIEnv實(shí)例裝載并處理class類
  • JVM加載類
下面看看一個(gè)java代碼是怎么運(yùn)行起來的:
參考文:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/

四、JVM的內(nèi)存管理這里有一篇文章講的很詳細(xì):http://developer.51cto.com/art/201303/387175.htmJVM的內(nèi)存結(jié)構(gòu)分為6塊:PC Register(PC寄存器)、JVM堆、JVM棧、方法區(qū)域、運(yùn)行時(shí)常量、本地方法堆棧。如下圖示意:對(duì)于開發(fā)來說主要關(guān)注的還是堆和棧。JVM一些參數(shù)設(shè)置:-Xss:這個(gè)參數(shù)就是用來指定棧的大小-Xms:設(shè)置JVM啟動(dòng)時(shí)最小的堆內(nèi)存大小-Xmx:設(shè)置JVM堆的最大內(nèi)存大小-XX:PermSize及-XX:MaxPermSize指定方法區(qū)域(MethodArea)的初始值與最大值MethodArea對(duì)應(yīng)的是持久代(PermanetGeneration),所以設(shè)置Perm的大小很重要,否則會(huì)報(bào)java.lang.OutOfMemoryError: PermGen space。五、垃圾收集器(Garbage Collector,GC)垃圾收集器這個(gè)東西對(duì)于程序員來說可謂是一種解脫,可以不用顯式釋放內(nèi)存了。這種神奇的療效還是要看看他的基本原理了解一下情況才行。下面摘了一段話:
有幾種垃圾收集的基本策略:引用計(jì)數(shù)、標(biāo)記-清除、標(biāo)記-整理 (mark-compact) 和復(fù)制。此外,一些算法可以以增量方式完成它們的工作(不需要一次收集整個(gè)堆,使得收集暫停時(shí)間更短),一些算法可以在用戶程序運(yùn)行時(shí)運(yùn)行(并發(fā)收集)。其他算法則必須在用戶程序暫停時(shí)一次進(jìn)行整個(gè)收集(即所謂的stop-the-world收集器)。最后,還有混合型的收集器,如 1.2 和以后版本的 JDK 使用的分代收集器,它對(duì)堆的不同區(qū)域使用不同的收集算法。——摘自developerWorks 中國
這里就回收的算法來看主要就上面列出來的幾種,其中比較重要的是“復(fù)制”和“標(biāo)識(shí)-整理”有必要理解一下。復(fù)制收集器就是劃分兩個(gè)對(duì)等空間,其中一個(gè)放活躍對(duì)象,另一個(gè)空著,等第一個(gè)滿了就復(fù)制活躍對(duì)象到另一個(gè)空著的,然后將這兩個(gè)空間角色換一下。這里有個(gè)重點(diǎn)就是只復(fù)制活躍對(duì)象。活躍對(duì)象通常就是可到達(dá)的對(duì)象也就是不用回收的內(nèi)存,換言之就是除此之外的就是垃圾,那么這樣的好處就是復(fù)制一次后,將那些垃圾一次回收就行了。而且復(fù)制后內(nèi)存空間是會(huì)經(jīng)過整理的連續(xù)的,不會(huì)有碎片問題。標(biāo)識(shí)-整理收集器算法結(jié)合了標(biāo)記-清除和復(fù)制,代價(jià)是增加了一些收集復(fù)雜性。與標(biāo)記-清除類似,標(biāo)記-整理是兩階段過程,在標(biāo)記階段訪問并標(biāo)記每個(gè)活躍對(duì)象。然后,復(fù)制標(biāo)記的對(duì)象,使所有活躍對(duì)象被整理到堆的底部。如果每一次收集時(shí)進(jìn)行徹底的整理,那么得到的堆就類似于復(fù)制收集器的結(jié)果 ―― 在堆的活躍部分與自由部分有明確的界線,這樣分配成本與復(fù)制收集器相當(dāng)。長壽的對(duì)象趨向于沉在堆的底部,這樣就不會(huì)像在復(fù)制收集器中那樣反復(fù)復(fù)制它們。既然是垃圾回收,那么自然有一個(gè)問題什么是垃圾?
由分配器分配的,但是用戶程序不可到達(dá)的內(nèi)存塊。不可到達(dá)是什么意思?可以以兩種方式之一訪問內(nèi)存塊 ―― 或者用戶程序在根 (root)中有對(duì)這一內(nèi)存塊的引用,或者在另一個(gè)可到達(dá)的塊中有對(duì)這個(gè)塊的引用。——摘自developerworks
這里面提到了一個(gè)很關(guān)鍵的點(diǎn),就是根(Root),那什么才是Root?這個(gè)得好好了解一下。下面是GC Root的種類:
  • Class- 由系統(tǒng)類加載器(system class loader)加載的對(duì)象,這些類是不能夠被回收的,他們可以以靜態(tài)字段的方式保存持有其它對(duì)象。我們需要注意的一點(diǎn)就是,通過用戶自定義的類加載器加載的類,除非相應(yīng)的java.lang.Class實(shí)例以其它的某種(或多種)方式成為roots,否則它們并不是roots,.
  • Thread- 活著的線程
  • Stack Local- Java方法的local變量或參數(shù)
  • JNI Local- JNI方法的local變量或參數(shù)
  • JNI Global- 全局JNI引用
  • Monitor Used- 用于同步的監(jiān)控對(duì)象
  • Held by JVM- 用于JVM特殊目的由GC保留的對(duì)象,但實(shí)際上這個(gè)與JVM的實(shí)現(xiàn)是有關(guān)的。可能已知的一些類型是:系統(tǒng)類加載器、一些JVM知道的重要的異常類、一些用于處理異常的預(yù)分配對(duì)象以及一些自定義的類加載器等。然而,JVM并沒有為這些對(duì)象提供其它的信息,因此就只有留給分析分員去確定哪些是屬于"JVM持有"的了。
分代垃圾收集有人做過分析,應(yīng)用程序堆中的對(duì)象有98%的對(duì)象存活的時(shí)間比較短,還有一些是會(huì)存活很長,甚至?xí)S著應(yīng)用程序整個(gè)生命周期。將這兩類對(duì)象可以稱為年輕代和持久代。
分代收集器(generializational collector)將堆分為多個(gè)代。在年輕的代中創(chuàng)建對(duì)象,滿足某些提升標(biāo)準(zhǔn)的對(duì)象,如經(jīng)歷了特定次數(shù)垃圾收集的對(duì)象,將被提升到下一更老的代。分代收集器對(duì)不同的代可以自由使用不同的收集策略,對(duì)各代分別進(jìn)行垃圾收集。——摘自developerworks
可以看出分代垃圾收集主要是將對(duì)象以生命周期進(jìn)行歸類,然后針對(duì)不同的類別使用不同的回收算法,這樣就可以更優(yōu)的進(jìn)行跟蹤回收。JDK 1.4.1 默認(rèn)收集器

在默認(rèn)情況下,JDK 1.4.1 將堆分為兩部分,一個(gè)年輕的代和一個(gè)老的代(實(shí)際上,還有第三部分――永久空間,它用于存儲(chǔ)裝載的類和方法對(duì)象)。借助于復(fù)制收集器,年輕的代又分為一個(gè)創(chuàng)建空間(通常稱為Eden)和兩個(gè)生存半空間。

老的代使用標(biāo)記-整理收集器。對(duì)象在經(jīng)歷了幾次復(fù)制后提升到老的代。小的收集將活的對(duì)象從 Eden 和一個(gè)生存半空間復(fù)制到另一個(gè)生存半空間,并可能提升一些對(duì)象到老的代。大的收集(major collection)既會(huì)收集年輕的代,也會(huì)收集老的代。System.gc()方法總是觸發(fā)一個(gè)大的收集,這就是應(yīng)該盡量少用(如果不能完全不用的話)System.gc()的原因之一,因?yàn)榇蟮氖占刃〉氖占ㄙM(fèi)長得多的時(shí)間。沒有辦法以編程方式觸發(fā)小的收集。

——摘自developerworks

總的機(jī)制就是讓壽命長的對(duì)象逐步往老的代中放,這樣可以優(yōu)化收集的時(shí)機(jī),減少收集暫停給應(yīng)用程序帶來的影響?;旧螱C的簡單機(jī)制就這些內(nèi)容。參考文:http://blog.csdn.net/java2000_wl/article/details/8022293http://www.ibm.com/developerworks/cn/java/j-jtp11253/
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 本溪| 隆德县| 伊宁县| 舞钢市| 二手房| 阳原县| 荣成市| 朔州市| 信宜市| 开阳县| 安塞县| 漾濞| 新疆| 民丰县| 盖州市| 河曲县| 苏尼特左旗| 江城| 平塘县| 保康县| 滕州市| 南汇区| 马公市| 阜平县| 丽江市| 灌云县| 仁化县| 高平市| 祁门县| 九龙县| 大同市| 江山市| 安仁县| 赫章县| 庆阳市| 灵台县| 呼图壁县| 家居| 进贤县| 甘谷县| 昭平县|