自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解JVM運(yùn)行原理及Stack和Heap的實(shí)現(xiàn)過程

云計(jì)算 虛擬化
因?yàn)榫€上系統(tǒng)遇到CPU100%的問題,這種問題在流量較大時(shí)比較常見,因?yàn)镴DK自身有很多JVM調(diào)試工具,如jps、jstack、jmap、jhat、jstat等使用工具,在實(shí)際工作中使用這些工具進(jìn)行調(diào)試是十分必要的,一般通過上面工具就能定位并解決CPU100%的問題。

 [[267906]]

概述

因?yàn)榫€上系統(tǒng)遇到CPU100%的問題,這種問題在流量較大時(shí)比較常見,因?yàn)镴DK自身有很多JVM調(diào)試工具,如jps、jstack、jmap、jhat、jstat等使用工具,在實(shí)際工作中使用這些工具進(jìn)行調(diào)試是十分必要的,一般通過上面工具就能定位并解決CPU100%的問題。

實(shí)際上Java語言寫的源程序是通過Java編譯器,編譯成與平臺無關(guān)的‘字節(jié)碼程序’(.class文件,也就是0,1二進(jìn)制程序),然后在OS之上的Java解釋器中解釋執(zhí)行,而JVM是java的核心和基礎(chǔ),在java編譯器和os平臺之間的虛擬處理器。所以理解JVM運(yùn)行原理是很有必要的。

 

詳解JVM運(yùn)行原理及Stack和Heap的實(shí)現(xiàn)過程

 

JVM原理

1. JVM簡介

JVM是java的核心和基礎(chǔ),在java編譯器和os平臺之間的虛擬處理器。它是一種利用軟件方法實(shí)現(xiàn)的抽象的計(jì)算機(jī)基于下層的操作系統(tǒng)和硬件平臺,可以在上面執(zhí)行java的字節(jié)碼程序。

java編譯器只要面向JVM,生成JVM能理解的代碼或字節(jié)碼文件。Java源文件經(jīng)編譯成字節(jié)碼程序,通過JVM將每一條指令翻譯成不同平臺機(jī)器碼,通過特定平臺運(yùn)行。

2. Java語言運(yùn)行的過程

Java語言寫的源程序通過Java編譯器,編譯成與平臺無關(guān)的‘字節(jié)碼程序’(.class文件,也就是0,1二進(jìn)制程序),然后在OS之上的Java解釋器中解釋執(zhí)行。

 

詳解JVM運(yùn)行原理及Stack和Heap的實(shí)現(xiàn)過程

 

3. JVM執(zhí)行程序的過程

  • I. 加載class文件。
  • II. 管理并分配內(nèi)存。
  • III. 執(zhí)行垃圾收集。

JRE(java運(yùn)行時(shí)環(huán)境)由JVM構(gòu)造的java程序的運(yùn)行環(huán)境

 

詳解JVM運(yùn)行原理及Stack和Heap的實(shí)現(xiàn)過程

 

JVM中的Stack和Heap

在JVM中,內(nèi)存分為兩個(gè)部分,Stack(棧)和Heap(堆),這里,我們從JVM的內(nèi)存管理原理的角度來認(rèn)識Stack和Heap,并通過這些原理認(rèn)清Java中靜態(tài)方法和靜態(tài)屬性的問題。

1. 簡介

Stack(棧)是JVM的內(nèi)存指令區(qū)。Stack管理很簡單,push一定長度字節(jié)的數(shù)據(jù)或者指令,Stack指針壓棧相應(yīng)的字節(jié)位移;pop一定字節(jié)長度數(shù)據(jù)或者指令,Stack指針彈棧。Stack的速度很快,管理很簡單,并且每次操作的數(shù)據(jù)或者指令字節(jié)長度是已知的。所以Java基本數(shù)據(jù)類型,Java指令代碼,常量都保存在Stack中。

Heap(堆)是JVM的內(nèi)存數(shù)據(jù)區(qū)。Heap的管理很復(fù)雜,每次分配不定長的內(nèi)存空間,專門用來保存對象的實(shí)例。在Heap中分配一定的內(nèi)存來保存對象實(shí)例,實(shí)際上也只是保存對象實(shí)例的屬性值,屬性的類型和對象本身的類型標(biāo)記等,并不保存對象的方法(方法是指令,保存在Stack中),在Heap中分配一定的內(nèi)存保存對象實(shí)例和對象的序列化比較類似。而對象實(shí)例在Heap中分配好以后,需要在Stack中保存一個(gè)4字節(jié)的Heap內(nèi)存地址,用來定位該對象實(shí)例在Heap中的位置,便于找到該對象實(shí)例。

下圖為JVM的體系結(jié)構(gòu):

 

詳解JVM運(yùn)行原理及Stack和Heap的實(shí)現(xiàn)過程

 

2. 什么是數(shù)據(jù)、什么是指令,對象的方法和對象的屬性又是什么?

1)方法本身是指令的操作碼部分,保存在Stack中;

2)方法內(nèi)部變量作為指令的操作數(shù)部分,跟在指令的操作碼之后,保存在Stack中(實(shí)際上是簡單類型保存在Stack中,對象類型在Stack中保存地址,在Heap 中保存值);上述的指令操作碼和指令操作數(shù)構(gòu)成了完整的Java指令。

3)對象實(shí)例包括其屬性值作為數(shù)據(jù),保存在數(shù)據(jù)區(qū)Heap中。

非靜態(tài)的對象屬性作為對象實(shí)例的一部分保存在Heap中,而對象實(shí)例必須通過Stack中保存的地址指針才能訪問到。因此能否訪問到對象實(shí)例以及它的非靜態(tài)屬性值完全取決于能否獲得對象實(shí)例在Stack中的地址指針。

在JVM中,靜態(tài)屬性保存在Stack指令內(nèi)存區(qū),動(dòng)態(tài)屬性保存在Heap數(shù)據(jù)內(nèi)存區(qū)。

總結(jié):

1)棧是運(yùn)行時(shí)的單位,而堆是存儲的單位。

2)棧解決程序的運(yùn)行問題,即程序如何執(zhí)行,或者說如何處理數(shù)據(jù);堆解決的是數(shù)據(jù)存儲的問題,即數(shù)據(jù)怎么放、放在哪兒。

4. 為什么要把堆和棧區(qū)分出來呢?

***,從軟件設(shè)計(jì)的角度看,棧代表了處理邏輯,而堆代表了數(shù)據(jù)。這樣分開,使得處理邏輯更為清晰。分而治之的思想。這種隔離、模塊化的思想在軟件設(shè)計(jì)的方方面面都有體現(xiàn)。

第二,堆與棧的分離,使得堆中的內(nèi)容可以被多個(gè)棧共享(也可以理解為多個(gè)線程訪問同一個(gè)對象)。這種共享的收益是很多的。一方面這種共享提供了一種有效的數(shù)據(jù)交互方式(如:共享內(nèi)存),另一方面,堆中的共享常量和緩存可以被所有棧訪問,節(jié)省了空間。

第三,棧因?yàn)檫\(yùn)行時(shí)的需要,比如保存系統(tǒng)運(yùn)行的上下文,需要進(jìn)行地址段的劃分。由于棧只能向上增長,因此就會限制住棧存儲內(nèi)容的能力。而堆不同,堆中的對象是可以根據(jù)需要?jiǎng)討B(tài)增長的,因此棧和堆的拆分,使得動(dòng)態(tài)增長成為可能,相應(yīng)棧中只需記錄堆中的一個(gè)地址即可。

第四,面向?qū)ο缶褪嵌押蜅5?**結(jié)合。其實(shí),面向?qū)ο蠓绞降某绦蚺c以前結(jié)構(gòu)化的程序在執(zhí)行上沒有任何區(qū)別。但是,面向?qū)ο蟮囊?,使得對待問題的思考方式發(fā)生了改變,而更接近于自然方式的思考。當(dāng)我們把對象拆開,你會發(fā)現(xiàn),對象的屬性其實(shí)就是數(shù)據(jù),存放在堆中;而對象的行為(方法),就是運(yùn)行邏輯,放在棧中。我們在編寫對象的時(shí)候,其實(shí)即編寫了數(shù)據(jù)結(jié)構(gòu),也編寫的處理數(shù)據(jù)的邏輯。

程序要運(yùn)行總是有一個(gè)起點(diǎn)的。同C語言一樣,java中的Main就是那個(gè)起點(diǎn)。無論什么java程序,找到main就找到了程序執(zhí)行的入口

5. 堆中存什么?棧中存什么?

1)堆中存的是對象。棧中存的是基本數(shù)據(jù)類型和堆中對象的引用。一個(gè)對象的大小是不可估計(jì)的,或者說是可以動(dòng)態(tài)變化的,但是在棧中,一個(gè)對象只對應(yīng)了一個(gè)4btye的引用。

2)為什么不把基本類型放堆中呢?因?yàn)槠湔加玫目臻g一般是1~8個(gè)字節(jié)——需要空間比較少,而且因?yàn)槭腔绢愋?,所以不會出現(xiàn)動(dòng)態(tài)增長的情況——長度固定,因此棧中存儲就夠了,如果把他存在堆中是沒有什么意義的(還會浪費(fèi)空間,后面說明)??梢赃@么說,基本類型和對象的引用都是存放在棧中,而且都是幾個(gè)字節(jié)的一個(gè)數(shù),因此在程序運(yùn)行時(shí),他們的處理方式是統(tǒng)一的。但是基本類型、對象引用和對象本身就有所區(qū)別了,因?yàn)橐粋€(gè)是棧中的數(shù)據(jù)一個(gè)是堆中的數(shù)據(jù)。最常見的一個(gè)問題就是,Java中參數(shù)傳遞時(shí)的問題。

3)Java中的參數(shù)傳遞時(shí)傳值呢?還是傳引用?程序運(yùn)行永遠(yuǎn)都是在棧中進(jìn)行的,因而參數(shù)傳遞時(shí),只存在傳遞基本類型和對象引用的問題。不會直接傳對象本身。

Java在方法調(diào)用傳遞參數(shù)時(shí),因?yàn)闆]有指針,所以它都是進(jìn)行傳值調(diào)用

PS:堆和棧中,棧是程序運(yùn)行最根本的東西。程序運(yùn)行可以沒有堆,但是不能沒有棧。而堆是為棧進(jìn)行數(shù)據(jù)存儲服務(wù),說白了堆就是一塊共享的內(nèi)存。不過,正是因?yàn)槎押蜅5姆蛛x的思想,才使得Java的垃圾回收成為可能。

深入理解JVM原理對于我們平時(shí)調(diào)試問題還是很有幫助的,運(yùn)維不僅僅是學(xué)一些Linux命令就可以的,如果要往深方面研究的話很多時(shí)候開發(fā)的東西要需要會一點(diǎn)的。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2010-03-15 14:24:59

StackHeapJVM

2013-05-17 15:38:22

iOS開發(fā)iOS堆棧heap stack

2009-07-09 14:01:22

JVM工作原理

2010-09-26 08:50:11

JVM工作原理

2010-09-17 15:25:03

JAVAJVM

2019-09-02 14:53:53

JVM內(nèi)存布局GC

2012-03-01 10:51:37

JavaJVM

2020-01-14 14:37:29

JVMJava體系

2009-07-10 14:55:34

2021-06-30 10:32:33

反射多態(tài)Java

2021-09-06 13:12:05

前端JavaScript編程

2020-01-06 10:58:18

JvmGC機(jī)制虛擬機(jī)

2009-06-11 16:25:44

EJB2.0EJB

2021-02-07 09:36:20

LongAdderJDK8開發(fā)

2024-08-09 11:50:00

2023-07-11 08:00:00

2010-09-16 14:42:44

JVM

2022-03-17 08:55:43

本地線程變量共享全局變量

2009-09-15 16:08:00

2018-05-23 10:59:14

DNS原理解析
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號