JAVA與c,C++有很大的不同就是JAVA語言開發者不需要關注內存信息,不會顯式的直接操作內存,而是通過JVM虛擬機來實現。
摘要:JVM作為Java的核心技術,很多朋友想必也有研究。一直都在關注JVM方面的技術,以前看過一些書籍和網上的資料,自己也發了些Blog文章,不過還是沒有徹底的了解JVM機制,最近有時間研究了研究,特此寫下一篇文章并結合筆者多年實踐以揭露JVM實現機理。
jstat工具特別強大,有眾多的可選項,詳細查看堆內各個部分的使用量,以及加載類的數量。使用時,需加上查看進程的進程id,和所選參數。以下詳細介紹各個參數的意義。 jstat -class pid:顯示加載class的數量,及所占空間等信息。
深入理解JVM1說起Java,人們首先想到的是Java編程語言,然而事實上,Java是一種技術,它由四方面組成:Java編程語言、Java類文件格式、Java虛擬機和Java應用程序接口(Java API)。
以前我作為java 開發人員,用的都是sun 的JVM (這也是當今最好用的虛擬機),由于垃圾收集的工作都是交給JVM 做,只要編碼的時候注意不要在靜態的集合對象中只添加對象,而不刪除對象的情況發生,就可以避免內存泄漏,所以自己從沒有認真考慮過要將GC 好好學習一下;然而實際的工作表明,不深入的學習GC 的原理,很難解決生產中的問題。 學習開始從理解JVM 的GC 工作原理入手。垃圾收集的過程主要分三個步驟:標記(mark ),清除(sweep ),整理(compact )。標記過程就是看看在JVM 堆中有哪些對象還有用,哪些對象不用了,有用的對象就作個標記,不用的對象就不作標記;對未作標記的對象(即不用的對象)就作第二步清除;當清除完以后,由于有用的對象此時是分散的分布在JVM 堆中,JVM 堆就會有許多堆碎片,因而需要做第三步整理;整理(也有人翻譯成“壓縮”,實際上最準確的翻譯是“使緊湊”)就是將散放在JVM 堆中的有用對象移動到堆底部,削除堆碎片。
Java棧是與每一個線程關聯的,JVM在創建每一個線程的時候,會分配一定的棧空間給線程。它主要用來存儲線程執行過程中的局部變量,方法的返回值,以及方法調用上下文。棧空間隨著線程的終止而釋放。StackOverflowError:如果在線程執行的過程中,棧空間不夠用,那么JVM就會拋出此異常,這種情況一般是死遞歸造成的。
選擇合適的Java虛擬機, Java內存管理的基本概念,GC次數過多消耗時間過長的原因和癥狀 內存不足和內存泄漏錯誤的原因和癥狀, 診斷、定位和解決內存不足和內存泄漏錯誤, 使用分析工具解決內存不足和內存泄漏錯誤, 預防內存不足和內存泄漏, OutOfMemory錯誤實例。
Java的堆是一個運行時數據區,類的(對象從中分配空間。這些對象通過new、newarray、anewarray和multianewarray等指令建立,它們不需要程序代碼來顯式的釋放。堆是由垃圾回收來負責的,堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,因為它是在運行時動態分配內存的,Java的垃圾收集器會自動收走這些不再使用的數據。但缺點是,由于要在運行時動態分配內存,存取速度較慢。
Java技術與Java虛擬機說起Java,人們首先想到的是Java編程語言,然而事實上,Java是一種技術,它由四方面組成:Java編程語言、Java類文件格式、Java虛擬機和Java應用程序接口(Java API)。它們的關系如下圖所示:圖1??Java四個方面的關系運行期環境代表著Java平臺,開發人員編寫Java代碼(.java文件),然后將之編譯成字節碼(.class文件)。最后字節碼被裝入內存,一旦字節碼進入虛擬機,它就會被解釋器解釋執行,或者是被即時代碼發生器有選擇的轉換成機器碼執行。從上圖也可以看出Java平臺由Java虛擬機和Java應用程序接口搭建,Java語言則是進入這個平臺的通道,用Java語言編寫并編譯的程序可以運行在這個平臺上。這個平臺的結構如下圖所示:在Java平臺的結構中,可以看出,Java虛擬機(JVM)處在核心的位置,是程序與底層操作系統和硬件無關的關鍵。它的下方是移植接口,移植接口由兩部分組成:適配器和Java操作系統,其中依賴于平臺的部分稱為適配器;JVM通過移植接口在具體的平臺和操作系統上實現;在JVM的上方是Java的基本類庫和擴展類庫以及它們的API,利用JavaAPI編寫的應用程序(application)和小程序(Javaapplet)可以在任何Java平臺上運行而無需考慮底層平臺,就是因為有Java虛擬機(JVM)實現了程序與操作系統的分離,從而實現了Java的平臺無關性。那么到底什么是Java虛擬機(JVM)呢?通常我們談論JVM時,我們的意思可能是:對JVM規范的的比較抽象的說明;對JVM的具體實現;在程序運行期間所生成的一個JVM實例。對JVM規范的的抽象說明是一些概念的集合,它們已經在書《TheJavaVirtualMachineSpecification》(《Java虛擬機規范》)中被詳細地描述了;對JVM的具體實現要么是軟件,要么是軟件和硬件的組合,它已經被許多生產廠商所實現,并存在于多種平臺之上;運行Java程序的任務由JVM的運行期實例單個承擔。在本文中我們所討論的Java虛擬機(JVM)主要針對第三種情況而言。它可以被看成一個想象中的機器,在實際的計算機上通過軟件模擬來實現,有自己想象中的硬件,如處理器、堆棧、寄存器等,還有自己相應的指令系統。JVM在它的生存周期中有一個明確的任務,那就是運行Java程序,因此當Java程序啟動的時候,就產生JVM的一個實例;當程序運行結束的時候,該實例也跟著消失了。下面我們從JVM的體系結構和它的運行過程這兩個方面來對它進行比較深入的研究。
Java平臺自動集成了線程以及多處理器技術,這種集成程度比Java以前誕生的計算機語言要厲害很多,該語言針對多種異構平臺的平臺獨立性而使用的多線程技術支持也是具有開拓性的一面,有時候在開發Java同步和線程安全要求很嚴格的程序時,往往容易混淆的一個概念就是內存模型。究竟什么是內存模型?內存模型描述了程序中各個變量(實例域、靜態域和數組元素)之間的關系,以及在實際計算機系統中將變量存儲到內存和從內存中取出變量這樣的底層細節,對象最終是存儲在內存里面的,這點沒有錯,但是編譯器、運行庫、處理器或者系統緩存可以有特權在變量指定內存位置存儲或者取出變量的值。【JMM】(JavaMemoryModel的縮寫)允許編譯器和緩存以數據在處理器特定的緩存(或寄存器)和主存之間移動的次序擁有重要的特權,除非程序員使用了final或synchronized明確請求了某些可見性的保證。