學習JVM知識的必要性
Java語言針對記憶體實行的是自動管理機制,不需要程式員在代碼里寫釋放記憶體,垃圾回收的代碼,JVM幫助你實作了這些功能,Java雖然有垃圾回識訓制,但是有些垃圾是回收不了的,還是會造成記憶體泄漏,記憶體溢位等錯誤,如果你對JVM記憶體模型及運行機制不了解的話,當專案出現問題時,會束手無措,
專案啟動后,JVM是如何作業的
1、服務器啟動時,源代碼被Java編譯器,編譯為位元組碼檔案(.class),
2、JVM中的類加載器將所有的位元組碼檔案加載進JVM空間,
3、JVM執行引擎執行這些位元組碼檔案,
4、執行的程序中,產生了很多資料,這些資料固定的存在某塊空間,這塊空間就是我們經常提到的JVM記憶體,
JVM記憶體劃分
JVM共分為五個部分,分別是堆疊、堆、方法區、程式計數器,本地方法堆疊,我們運行的每一個專案都是一個行程,一個行程包含多個執行緒,
堆疊
執行緒私有,
堆疊解決程式的運行問題,即程式如何執行,或者說如何處理資料,
在虛擬機中跑的所有的執行緒,每一個執行緒,都有一個自己的執行緒堆疊,這個堆疊是私有的,別人不能訪問你的東西,執行緒堆疊包括了這個執行緒現在執行的方法,以及這個節點的相關資訊,
每個執行緒堆疊由一個個的堆疊幀組成,每個堆疊幀對應一個呼叫的方法,
簡而言之,堆疊執行位元組碼檔案中的java方法,
堆
執行緒共享,
堆是記憶體最大的一塊區域,解決的是資料存盤的問題,存放物件的實體,
我們經常遇到的記憶體報錯,基本上都是這里搞出來的,比如你創建的實體物件太多了,堆的空間塞滿了,
堆內部分為兩個空間,新生代,老年代,
新創建的物件都在新生代這一塊,如果經過多次GC仍然活著,就會被轉移到老年代,
簡而言之,出了問題,基本上都是堆記憶體分配的鍋,
方法區
方法區有三個名字,方法區,非堆,永久代,
它和堆有點相像,都是執行緒共享,但是它存盤的東西不一樣,而且GC一般也不會跑到這里來,主要存盤類資訊,常量,靜態變數等資料,
簡而言之,不用管方法區是啥,
程式計數器
執行緒私有,位元組碼行號指示器,程式計數器是JVM規范中唯一一個沒有任何OutOfMemoryError情況的區域,
簡而言之,這個東西,基本上,你不會跟它有打交道的時候,
本地方法堆疊
執行緒私有,存放字面量及符號參考,
簡而言之,本地方法堆疊執行Native方法,Native方法是指在Java中呼叫其他編程語言的方法,如果你沒有用,那這個東西基本與你無瓜,
總結
五個區域,只有堆和方法區是執行緒共享的,其他都是執行緒私有,
Java會造成記憶體泄漏嗎?
從概念上講,Java有垃圾回識訓制不會存在記憶體泄漏問題,
從現實中看,每個小區都有保潔對垃圾桶進行清理,偶爾會有那么一兩個忘記清理了,
即有GC歸有GC,總是有些藏污納垢的地方,
在實際開發中,存在一些沒有什么用的物件,這些物件不被GC回收,因而會導致記憶體泄漏的發生,
比如:Hibernate的Session(一級快取)中的物件屬于持久態,垃圾回收器是不會回收這些物件的,然而這些物件中可能存在無用的垃圾物件,如果不及時關閉(close)或清空(flush)一級快取就可能導致記憶體泄露,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/195035.html
標籤:其他
