一、java內(nèi)存組成介紹:堆(Heap)
和非堆(Non-heap)
內(nèi)存
按照官方的說法:“Java 虛擬機(jī)具有一個(gè)堆,堆是運(yùn)行時(shí)數(shù)據(jù)區(qū)域,所有類實(shí)例和數(shù)組的內(nèi)存均從此處分配。
堆是在 Java 虛擬機(jī)啟動時(shí)創(chuàng)建的?!薄霸贘VM中堆之外的內(nèi)存稱為非堆內(nèi)存(Non-heap memory)”。可以看出JVM主要管理兩種類型的內(nèi)存:堆和非堆。
簡單來說堆就是Java代碼可及的內(nèi)存,是留給開發(fā)人員使用的;非堆就是JVM留給 自己用的,所以方法區(qū)、JVM內(nèi)部處理或優(yōu)化所需的內(nèi)存(如JIT編譯后的代碼緩存)、每個(gè)類結(jié)構(gòu)(如運(yùn)行時(shí)常數(shù)池、字段和方法數(shù)據(jù))以及方法和構(gòu)造方法 的代碼都在非堆內(nèi)存中。
二、JVM內(nèi)存區(qū)域模型
1.方法區(qū) 也稱”永久代” 、“非堆”, 它用于存儲虛擬機(jī)加載的類信息、常量、靜態(tài)變量、是各個(gè)線程共享的內(nèi)存區(qū)域。默認(rèn)最小值為16MB,最大值為64MB,可以通過-XX:PermSize
和 -XX:MaxPermSize
參數(shù)限制方法區(qū)的大小。
運(yùn)行時(shí)常量池:是方法區(qū)的一部分,其中的主要內(nèi)容來自于JVM對Class的加載。
Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項(xiàng)信息是常量池,用于存放編譯器生成的各種符號引用,這部分內(nèi)容將在類加載后放到方法區(qū)的運(yùn)行時(shí)常量池中。
2.虛擬機(jī)棧
描述的是java 方法執(zhí)行的內(nèi)存模型:每個(gè)方法被執(zhí)行的時(shí)候 都會創(chuàng)建一個(gè)“棧幀”用于存儲局部變量表(包括參數(shù))、操作棧、方法出口等信息。每個(gè)方法被調(diào)用到執(zhí)行完的過程,就對應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過程。聲明周期與線程相同,是線程私有的。
局部變量表存放了編譯器可知的各種基本數(shù)據(jù)類型(boolean
、byte
、char
、short
、int
、float
、long
、double
)、對象引用(引用指針,并非對象本身),其中64位長度的long和double類型的數(shù)據(jù)會占用2個(gè)局部變量的空間,其余數(shù)據(jù)類型只占1個(gè)。
局部變量表所需的內(nèi)存空間在編譯期間完成分配,當(dāng)進(jìn)入一個(gè)方法時(shí),這個(gè)方法需要在棧幀中分配多大的局部變量是完全確定的,在運(yùn)行期間棧幀不會改變局部變量表的大小空間。
3.本地方法棧
與虛擬機(jī)?;绢愃?,區(qū)別在于虛擬機(jī)棧為虛擬機(jī)執(zhí)行的java方法服務(wù),而本地方法棧則是為Native方法服務(wù)。
4.堆
也叫做java 堆、GC堆是java虛擬機(jī)所管理的內(nèi)存中最大的一塊內(nèi)存區(qū)域,也是被各個(gè)線程共享的內(nèi)存區(qū)域,在JVM啟動時(shí)創(chuàng)建。該內(nèi)存區(qū)域存放了對象實(shí)例及數(shù)組(所有new的對象)。
其大小通過-Xms
(最小值)和-Xmx
(最大值)參數(shù)設(shè)置,-Xms為JVM啟動時(shí)申請的最小內(nèi)存,默認(rèn)為操作系統(tǒng)物理內(nèi)存的1/64但小于1G,-Xmx
為JVM可申請的最大內(nèi)存,默認(rèn)為物理內(nèi)存的1/4但小于1G,默認(rèn)當(dāng)空余堆內(nèi)存小于40%時(shí),JVM會增大Heap到-Xmx
指定的大小,可通過-XX:MinHeapFreeRation=
來指定這個(gè)比列;當(dāng)空余堆內(nèi)存大于70%時(shí),JVM會減小heap的大小到-Xms指定的大小,可通過XX:MaxHeapFreeRation=
來指定這個(gè)比列,對于運(yùn)行系統(tǒng),為避免在運(yùn)行時(shí)頻繁調(diào)整Heap的大小,通常-Xms與-Xmx的值設(shè)成一樣。
由于現(xiàn)在收集器都是采用分代收集算法,堆被劃分為新生代和老年代。新生代主要存儲新創(chuàng)建的對象和尚未進(jìn)入老年代的對象。老年代存儲經(jīng)過多次新生代GC(Minor GC)任然存活的對象。
新生代: 程序新創(chuàng)建的對象都是從新生代分配內(nèi)存,新生代由
Eden Space
和兩塊相同大小的Survivor Space
(通常又稱S0和S1或From和To)構(gòu)成,可通過-Xmn參數(shù)來指定新生代的大小,也可以通過-XX:SurvivorRation
來調(diào)整Eden Space
及Survivor Space
的大小。老年代: 用于存放經(jīng)過多次新生代GC任然存活的對象,例如緩存對象,新建的對象也有可能直接進(jìn)入老年代,主要有兩種情況:
1、大對象,可通過啟動參數(shù)設(shè)置
-XX:PretenureSizeThreshold=1024
(單位為字節(jié),默認(rèn)為0)來代表超過多大時(shí)就不在新生代分配,而是直接在老年代分配。2、大的數(shù)組對象,切數(shù)組中無引用外部對象。 老年代所占的內(nèi)存大小為-Xmx對應(yīng)的值減去-Xmn對應(yīng)的值。
?
Young?Generation????????即圖中的Eden?+?From?Space?+?To?Space Eden????????????????????存放新生的對象 Survivor?Space??????????有兩個(gè),存放每次垃圾回收后存活的對象 Old?Generation??????????Tenured?Generation?即圖中的Old?Space? ????????????????????????主要存放應(yīng)用程序中生命周期長的存活對象
5.程序計(jì)數(shù)器
是最小的一塊內(nèi)存區(qū)域,它的作用是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器,在虛擬機(jī)的模型里,字節(jié)碼解釋器工作時(shí)就是通過改變這個(gè)計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴計(jì)數(shù)器完成。
三、直接內(nèi)存
直接內(nèi)存并不是虛擬機(jī)內(nèi)存的一部分,也不是Java虛擬機(jī)規(guī)范中定義的內(nèi)存區(qū)域。jdk1.4中新加入的NIO,引入了通道與緩沖區(qū)的IO方式,它可以調(diào)用Native方法直接分配堆外內(nèi)存,這個(gè)堆外內(nèi)存就是本機(jī)內(nèi)存,不會影響到堆內(nèi)存的大小。
四、Java堆內(nèi)存的10個(gè)要點(diǎn)
Java堆內(nèi)存是操作系統(tǒng)分配給JVM的內(nèi)存的一部分。
當(dāng)我們創(chuàng)建對象時(shí),它們存儲在Java堆內(nèi)存中.
為了便于垃圾回收,Java堆空間分成三個(gè)區(qū)域,分別叫作New Generation, Old Generation或叫作Tenured Generation,還有Perm Space。
你可以通過用JVM的命令行選項(xiàng) -Xms, -Xmx, -Xmn來調(diào)整Java堆空間的大小。不要忘了在大小后面加上”M”或者”G”來表示單位。舉個(gè)例子,你可以用 -Xmx256m來設(shè)置堆內(nèi)存最大的大小為256MB。
你可以用JConsole或者 Runtime.maxMemory(), Runtime.totalMemory(), Runtime.freeMemory()來查看Java中堆內(nèi)存的大小。
你可以使用命令“jmap”來獲得heap dump,用“jhat”來分析heap dump。
Java堆空間不同于??臻g,??臻g是用來儲存調(diào)用棧和局部變量的。
Java垃圾回收器是用來將死掉的對象(不再使用的對象)所占用的內(nèi)存回收回來,再釋放到Java堆空間中。
當(dāng)你遇到j(luò)ava.lang.outOfMemoryError時(shí),不要緊張,有時(shí)候僅僅增加堆空間就可以了,但如果經(jīng)常出現(xiàn)的話,就要看看Java程序中是不是存在內(nèi)存泄露了。
- 請使用Profiler和Heap dump分析工具來查看Java堆空間,可以查看給每個(gè)對象分配了多少內(nèi)存。
更多相關(guān)知識請關(guān)注java基礎(chǔ)教程欄目
Atas ialah kandungan terperinci JVM的內(nèi)部結(jié)構(gòu)及運(yùn)行機(jī)制. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undress AI Tool
Gambar buka pakaian secara percuma

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Untuk mengendalikan transaksi JDBC dengan betul, anda mesti terlebih dahulu mematikan mod komit automatik, kemudian melakukan pelbagai operasi, dan akhirnya melakukan atau mengembalikan semula hasilnya; 1. Panggil Conn.SetAutOcommit (palsu) untuk memulakan transaksi; 2. Melaksanakan pelbagai operasi SQL, seperti memasukkan dan mengemaskini; 3. Panggil Conn.Commit () jika semua operasi berjaya, dan hubungi conn.rollback () jika pengecualian berlaku untuk memastikan konsistensi data; Pada masa yang sama, cuba-dengan-sumber harus digunakan untuk menguruskan sumber, mengendalikan pengecualian dengan betul dan menutup sambungan untuk mengelakkan kebocoran sambungan; Di samping itu, adalah disyorkan untuk menggunakan kolam sambungan dan menetapkan mata simpan untuk mencapai rollback separa, dan menyimpan urus niaga sesingkat mungkin untuk meningkatkan prestasi.

THEJVMenableSjava's "Writeonce, Runanywhere" keupayaanByExecutingByteCodeThroughFourMaincomponents: 1.TheClassloadersubsystemloads, pautan, danInitializes.ClassFilesusingBootstrap, Extension, andapplicationClassloaders, EnsuringseCureAndlazyCon

Gunakan kelas dalam pakej Java.Time untuk menggantikan kelas lama dan kelas kalendar; 2. Dapatkan tarikh dan masa semasa melalui LocalDate, LocalDateTime dan Tempatan Tempatan; 3. Buat tarikh dan masa tertentu menggunakan kaedah (); 4. Gunakan kaedah tambah/tolak untuk meningkatkan dan mengurangkan masa; 5. Gunakan zoneddatetime dan zonid untuk memproses zon waktu; 6. Format dan parse date string melalui DateTimeFormatter; 7. Gunakan segera untuk bersesuaian dengan jenis tarikh lama apabila perlu; pemprosesan tarikh di java moden harus memberi keutamaan untuk menggunakan java.timeapi, yang memberikan jelas, tidak berubah dan linear

Pra-formancetartuptimemoryusage, quarkusandmicronautleadduetocompile-timeprocessingandgraalvsupport, withquarkusoftenperforminglightbetterine serverless scenarios.tyvelopecosyste,

NetworkPortsandFireWallSworkTogethertoenableCommunicationWileensuringsecurity.1.networkportsarevirtualendpointsNumbered0-655 35, Withwell-KnownportsLike80 (http), 443 (https), 22 (ssh), dan25 (smtp) identitispecificservices.2.portsoperateovertcp (boleh dipercayai, c

Koleksi Sampah Java (GC) adalah mekanisme yang secara automatik menguruskan ingatan, yang mengurangkan risiko kebocoran ingatan dengan menuntut semula objek yang tidak dapat dicapai. 1.GC menghakimi kebolehcapaian objek dari objek akar (seperti pembolehubah stack, benang aktif, medan statik, dan lain -lain), dan objek yang tidak dapat dicapai ditandakan sebagai sampah. 2. Berdasarkan algoritma penandaan tanda, tandakan semua objek yang dapat dicapai dan objek yang tidak ditandai. 3. Mengamalkan strategi pengumpulan generasi: Generasi Baru (Eden, S0, S1) sering melaksanakan MinorGC; Orang tua melakukan kurang tetapi mengambil masa lebih lama untuk melakukan MajorGC; Metaspace Stores Metadata kelas. 4. JVM menyediakan pelbagai peranti GC: SerialGC sesuai untuk aplikasi kecil; ParallelGC meningkatkan throughput; CMS mengurangkan

GradleisthebetterChoiceFormostNewProjectSduetoitSsuperiorflexibility, Prestasi, danModernToolingSupport.1.Gradle'sGroovy/KOT lindslismoreconciseandexpressivethanmaven'sverbosexml.2.GradleOutPerformsMaveninBuildSpeedWithIncrementalcompilation, BuildCac

Defer digunakan untuk melaksanakan operasi tertentu sebelum fungsi pulangan, seperti sumber pembersihan; Parameter dinilai dengan serta-merta apabila menangguhkan, dan fungsi-fungsi dilaksanakan mengikut urutan terakhir (LIFO); 1. Pelbagai penahanan dilaksanakan dalam urutan terbalik pengisytiharan; 2. Biasanya digunakan untuk pembersihan yang selamat seperti penutupan fail; 3. Nilai pulangan yang dinamakan boleh diubah suai; 4. Ia akan dilaksanakan walaupun panik berlaku, sesuai untuk pemulihan; 5. Elakkan penyalahgunaan menangguhkan gelung untuk mengelakkan kebocoran sumber; Penggunaan yang betul boleh meningkatkan keselamatan kod dan kebolehbacaan.
