想要去阿里面試?你必須得跨過 JVM 這道坎!

?

概述

?

很多人想要到阿里巴巴、美團、京東等互聯網大公司去面試,但是現在互聯網大廠面試一般都必定會考核JVM相關的知識積累和實踐經驗,畢竟線上系統寫好代碼部署之后,每個工程師都必須關注JVM相關的東西,比如OOM、GC等問題.

?

所以一起來看看JVM的最基本的區域劃分以及工作原理,這個基本上是互聯網公司面試必問。

?

?

區域劃分

?

jvm的區域劃分如下所示:

?

?

?

大致就是分為:程序計數器,虛擬機棧,堆,方法區,本地方法棧,這幾個部分。

?

接下來我們從自己寫好的Java代碼如何通過JVM來運行的角度,來分析一下JVM里這些區域是如何支撐我們的Java代碼跑起來的。

?

?

程序計數器

?

假設我們有如下的一個類,就是最最基本的一個HelloWorld而已:

?

public class HelloWorld {public static void main(String[] args) {System.out.println("Hello World");}}

?

上面那段代碼首先會存在于 “.java” 后綴的文件里,這個文件就是java源代碼文件,但是這個文件是面向我們程序員的,計算機他是看不懂你寫的這段代碼的

?

所以此時就得通過編譯器,把“.java”后綴的源代碼文件編譯為“.class”后綴的字節碼文件。

?

這個“.class”后綴的字節碼文件里,存放的就是對你寫出來的代碼編譯好的字節碼了,這個字節碼才是計算器可以理解的一種語言,而不是我們寫出來的那一堆代碼。

?

這個字節碼看起來大概是下面這樣的:

?

?

?

這段字節碼并不是完全對照著HelloWorld那個類來寫的,就是給一段示例,讓大家知道“.java”翻譯成的“.class”是大概什么樣子的。

?

這里比如說“0: aload_0”這樣的,就是“字節碼指令”,他對應了一條一條的機器指令,計算機只有讀到這種機器碼指令,才知道具體應該要干什么。

?

比如說字節碼指令可能會讓計算機從內存里讀取某個數據,或者把某個數據寫入到內存里去,都有可能,各種各樣的指令,就會指示計算機去干各種各樣的事情。

?

所以現在首先明白一點,我們寫好的Java代碼是會被翻譯成字節碼的,對應各種字節碼指令。

?

那么Java代碼通過JVM跑起來的第一件事情就明確了, 首先Java代碼被編譯出來的字節碼指令一定會被一條一條的執行,這樣才能實現我們寫好的代碼被執行的效果。

?

那么在執行字節碼指令的時候,JVM里的程序計數器就是用來記錄每個線程當前執行的字節碼指令的位置的,記錄當前線程目前執行到了哪一條字節碼指令。

?

因為會有多個線程來并發的執行各種不同的代碼,所以每個線程都有自己的一個程序計數器,專門記錄當前這個線程目前執行到了哪一條字節碼指令了

?

下圖更加清晰的展示出了他們之間的關系。

?

?

?

?

Java虛擬機棧

?

Java代碼在執行的時候,一定是線程來執行某個方法中的代碼,比如哪怕就是上面的那個最基礎的HelloWorld代碼,也會有一個main線程來執行main方法里的代碼。

?

在方法里,經常會定義一些方法內的局部變量,比如下面這樣,就在方法里定義了一個局部變量“name”。

?

public void sayHello() {String name = "hello";}

?

所以JVM必須有一塊區域是來保存每個方法內的局部變量等等數據的,這個區域就是Java虛擬機棧

?

每個線程都會去執行各種方法的代碼,方法內還會嵌套調用其他的方法,所以首先每個線程都有自己的Java虛擬機棧。

?

如果線程執行了一個方法,那么就會被這個方法調用創建對應的一個棧幀,棧幀里就有這個方法的局部變量表 、操作數棧、動態鏈接、方法出口等東西,但是這里別的不太好理解,先理解一個局部變量就可以。

?

比如說一個線程調用了上面寫的“sayHello”方法,那么就會為“sayHello”方法創建一個棧幀,壓入線程自己的Java虛擬機棧里面去。

?

在棧幀的局部變量表里就會有“name”這個局部變量,下圖展示了這個過程。

?

?

?

接著如果“sayHello”方法調用了另外一個“greeting”方法 ,比如下面那樣的代碼:

?

?

?

那么這個時候會給“greeting”方法又創建一個棧幀壓入線程的Java虛擬機棧里,因為開始執行“greeting”方法了,而且“greeting”方法的棧幀的局部變量表里會有一個“greet”變量,這是“greeting”方法的局部變量。

?

?

?

?

接著如果“greeting”方法執行完畢了,就會把“greeting”方法對應的棧幀從Java虛擬機棧里給出棧,然后如果“sayHello”方法也執行完畢了,就會把“sayHello”方法也從Java虛擬機棧里出棧。

?

這就是JVM中的 “?Java虛擬機棧?” 這個組件的作用,調用執行任何方法的時候,都會給方法創建棧幀然后入棧。

?

而在棧幀里存放了這個方法對應的局部變量之類的數據,包括這個方法執行的其他相關的信息,方法執行完畢之后就出棧。

?

?

Java堆內存

?

JVM中有另外一個非常關鍵的區域,就是Java堆,這里就是存放我們在代碼中創建的各種對象的,比如說下面的代碼:

?

public void teach(String name) {Student student = new Student(name);student.study();}

?

上面的 “new Student(name)” 這個代碼就是創建了一個Student類型的對象實例,這個對象實例里面會包含一些數據。

?

比如說這個Student的“name”就是屬于這個對象實例的一個數據,那么類似Student這樣的對象,就會存放在Java堆內存里。

?

Java堆內存區域里會放入類似Student的對象,然后方法的棧幀的局部變量表里,這個引用類型的“student”局部變量就會存放Student對象的地址。

?

相當于你可以認為局部變量表里的“student”指向了Java堆里的Student對象。

?

看下圖會更加清晰一些。

?

?

?

?

方法區 / Metaspace

?

這個方法區是在JDK 1.8以前的版本里,代表JVM中的一塊區域,主要是放類似Student類自己的信息的,平時用到的各種類的信息,都是放在這個區域里的,還會有一些類似常量池的東西放在這個區域里。

?

但是在JDK 1.8以后,這塊區域的名字改了,叫做“Metaspace”,可以認為是“元數據空間”這樣的意思,這里當然主要其實還是存放我們自己寫的各種類相關的信息。

?

?

本地方法棧

?

其實在JDK很多底層API里,比如IO相關的,NIO相關的,網絡Socket相關的,如果大家去看他內部的源碼,會發現很多地方都不是Java代碼了。

?

很多地方都會去走native方法,去調用本地操作系統里面的一些方法,可能調用的都是c語言寫的方法,或者一些底層類庫,比如下面這樣的:

?

public native int hashCode();

?

在調用這種native方法的時候,就會有線程對應的本地方法棧,這個里面也是跟Java虛擬機棧類似的,也是存放各種native方法的局部變量表之類的信息。

?

?

堆外內存

?

還有一個區域,是不屬于JVM的,通過NIO中的allocateDirect這種API,可以在Java堆外分配內存空間。

?

然后通過Java虛擬機里的 DirectByteBuffer 來引用和操作堆外內存空間,其實很多技術都會用這種方式,因為有一些場景下,堆外內存分配可以提升性能。

?

?

總結

?

最后做一點總結,我們的Java代碼通過JVM來運行的時候,首先一定會一行一行執行編譯好的字節碼指令。

?

然后在執行的過程中,對于方法的調用,會通過Java虛擬機棧來為每個方法創建棧幀入棧和出棧,而且棧幀里有方法的局部變量表

?

接著對于對象的創建,會分配到Java堆內存里去

?

對于類信息的存儲,會放在方法區 / Metaspace這樣的區域里。

?

另外有兩塊特殊的區域:

    • 本地方法棧,是執行native方法時候用的棧,跟Java虛擬機棧是類似的

      ?

    • 堆外內存,是可以在Java堆外分配內存空間來存儲一些對象。

?

轉載:

原子彈大俠,阿里P8高級技術專家

經歷過每日百億流量的互聯網系統架構,尤其對上億用戶場景下的高并發系統架構設計以及性能優化相關領域有深入的研究。

轉載于:https://www.cnblogs.com/technologykai/articles/10869206.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/251773.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/251773.shtml
英文地址,請注明出處:http://en.pswp.cn/news/251773.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

醫學知識圖譜一

大綱 知識自動提取技術 醫學知識融合 醫學知識推理 轉載于:https://www.cnblogs.com/quietwalk/p/9000950.html

在一個div里,列表樣式圖片進行float,實現水平排序

<div class"xiangce"><ul> <li><a href"#"><img src"images/pic4.gif" alt"">產品名稱</a></li><li><a href"#"><img src"images/pic4.gif" alt"…

團隊開發git使用各種問題

參考:https://www.cnblogs.com/schaepher/p/4933873.html 問題-3:保持github上項目干凈&#xff0c;對于在不同機器上運行會不同的文件不予維護(如.idea/workspace.xml) 建議:對于項目輸出在項目目錄中的文件不予維護 對于IDE自動生成且與項目所在目錄有關的文件不予維護 將這些…

filebeat 亂碼

查看 文件的類型 [rootelk-node-1 rsyslog] # file 192.168.1.16.log 192.168.1.16.log: Non-ISO extended-ASCII text, with very long lines, with LF, NEL line terminators 如果命令返回結果說明改日志為utf-8&#xff0c;則logstash配置文件中charset設置為UTF-8 如果命令…

團隊編程項目代碼設計規范(爬取豆瓣電影top250)

基本格式 縮進 使用4個空格進行縮進 行寬 每行代碼盡量不超過80個字符 理由&#xff1a; 這在查看side-by-side的diff時很有幫助方便在控制臺下查看代碼太長可能是設計有缺陷換行 Python支持括號內的換行。這時有兩種情況。 第二行縮進到括號的起始處foo long_function_name(v…

程序員的浪漫

程序員的浪漫 馬上就到520了&#xff0c;各位小伙伴想好了準備什么禮物送個自己的另一半呢&#xff1f;還沒想好的注意啦&#xff01;&#xff01;現在還有機會&#xff0c;今天給大家分享一些程序員的浪漫創意禮物&#xff0c;希望你可以從中找到一些靈感。 One Link&#xff…

14-1 部署項目

1313轉載于:https://www.cnblogs.com/ZHONGZHENHUA/p/9011671.html

The listener supports no services

$ lsnrctl start 報錯提示: The listener supports no services The command completed successfully 如圖所示&#xff1a; 這樣啟動后遠程連接會報錯&#xff1a; oracle ORA-12514:TNS:listener does not currently know of service requested in connect descriptor 問題原…

Luogu P2577 [ZJOI2005]午餐

一道貪心類背包DP的好題 首先發現一個十分顯然的性質&#xff0c;沒有這個性質整道題目都難以下手&#xff1a; 無論兩隊的順序如何&#xff0c;總是讓吃飯慢的人先排隊 這是一個很顯然的貪心&#xff0c;因為如果讓吃飯慢的排在后面要更多的時間至少沒有這樣優 因此我們先按吃…

SEO【總結】by 2019年5月

2019獨角獸企業重金招聘Python工程師標準>>> 關鍵點&#xff1a; 1、代碼 1.1、seo前端代碼&#xff1a;基于Html代碼的SEOherf&#xff1a;https://my.oschina.net/u/2862573/blog/3030664 注意的要點&#xff1a; h1&#xff0c;h2的內容很關鍵 網頁的壓縮、靜態化…

Linux 系統的啟動順序

第一步&#xff1a;加載BIOS當你打開ia計算機的電源&#xff0c;計算機會首先加載計算機主板的BIOS信息&#xff0c;因為它包含了CPU的相關信息&#xff0c;設備啟動順序[安裝系統的U盤啟動順序]&#xff0c;內存信息&#xff0c;時鐘信息&#xff0c;PnP特性等等&#xff0c; …

Oracle數據庫 查看表是否是 索引組織表的方法

1. 最近在工作過程中發現 一個表插入很慢 以為是索引組織表, 所以一直有點糾結 但是發現 產品里面是沒有IOT的 于是找了下公司的OCP 問了下 如何查看 就是 user_tables 視圖里面的一個字段. 見圖: 轉載于:https://www.cnblogs.com/jinanxiaolaohu/p/9018037.html

Windows server 2016 搭建RDS服務

計算機的更新換代太快&#xff0c;新購置的計算機沒幾年便覺得運行速度越來越慢&#xff0c;尤其是在運行一些比較大的應用程序是&#xff0c;用戶總是抱怨運行速度太慢或者總是死機等問題。如果要更換新的計算機&#xff0c;又得不到領導的批準&#xff0c;因此對于企業來說&a…

π 的定義(極限)

圓周率&#xff0c;周長&#xff08;2πr&#xff09;與直徑&#xff08;2r&#xff09;的比值。在名稱上&#xff0c;是通過計算命名的。 1. 劉徽割圓與圓周率 π 通過圓內接正多邊形的周長來計算圓周長&#xff0c;是三世紀中期我國魏晉時代的數學家劉徽的光輝思想。 對于圓內…

前端開發瀏覽器兼容問題

csshack 1234567我很少使用hacker的&#xff0c;可能是個人習慣吧&#xff0c;我不喜歡寫的代碼IE不兼容&#xff0c;然后用hack來解決。不過hacker還是非常好用的。使用hacker我可以把瀏覽器分為3類&#xff1a;IE6 &#xff1b;IE7和遨游&#xff1b;其他&#xff08;IE8 chr…

springboot2.0 多數據源整合問題 At least one JPA metamodel must be present! ??at

2019獨角獸企業重金招聘Python工程師標準>>> 數據源代碼&#xff1a; 第一個讀取配置文件代碼&#xff1a; package com.datasource;import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.sp…

好書推薦

阿爾花剌子模:代數學. 喬治波利亞:怎樣解題:數學思維的新方法. Anany Levitin:算法設計與分析基礎.轉載于:https://www.cnblogs.com/mtl6906/p/7625290.html

docker實戰系列之搭建rabbitmq

1.搜索鏡像【注&#xff1a;因為我這里采用的是阿里云鏡像加速器,所以我直接在阿里云中搜索相關鏡像路徑】,點擊"詳情"查看公網拉取路徑 2.拉取鏡像 docker pull registry.cn-hangzhou.aliyuncs.com/jc/rabbitmq-3 3.查看拉取的鏡像 docker images 4.創建并運行容器【…

【hdu 6038】Function

【Link】:http://codeforces.com/contest/834/problem/C 【Description】 給你兩個排列a和b; a排列的長度為n,b排列的長度為m; a∈[0..n-1],b∈[0..m-1]; 然后讓你求一個函數f[i]; f[i]的定義域為0..n-1,值域為0..m-1 同時使得對于任意f[i],i∈[0..n-1]; f(i)bf(a[i])成…

樹中點對距離(點分治)

題目 給出一棵帶邊權的樹&#xff0c;問有多少對點的距離<Len 分析 這是一道點分治的經典題目&#xff0c;可以給點分治的初學者練手。 點分治&#xff0c;顧名思義就是把每個點分開了處理答案。 假設&#xff0c;目前做到了以x為根的子樹。 先求出子樹中每個點到根的距離\(…