java 筆面試第二彈

目錄##

1.內(nèi)存屏障
2.關(guān)鍵字native
3.偽共享
4.線程Dump文件
5.內(nèi)存溢出
6.jvm 配置和參數(shù)

1.內(nèi)存屏障##

目前有4種屏障----

LoadLoad屏障:對于這樣的語句Load1; LoadLoad; Load2,在Load2及后續(xù)讀取操作要讀取的數(shù)據(jù)被訪問前矾睦,保證Load1要讀取的數(shù)據(jù)被讀取完畢秽褒。

StoreStore屏障:對于這樣的語句Store1; StoreStore; Store2坐搔,在Store2及后續(xù)寫入操作執(zhí)行前拳氢,保證Store1的寫入操作對其它處理器可見践剂。

LoadStore屏障:對于這樣的語句Load1; LoadStore; Store2孝偎,在Store2及后續(xù)寫入操作被刷出前映皆,保證Load1要讀取的數(shù)據(jù)被讀取完畢挤聘。

StoreLoad屏障:對于這樣的語句Store1; StoreLoad; Load2,在Load2及后續(xù)所有讀取操作執(zhí)行前捅彻,保證Store1的寫入對所有處理器可見组去。它的開銷是四種屏障中最大的。在大多數(shù)處理器的實現(xiàn)中步淹,這個屏障是個萬能屏障从隆,兼具其它三種內(nèi)存屏障的功能诚撵。

2.native##

"A native method is a Java method whose implementation is provided by non-java code."

java中,native關(guān)鍵字說明其修飾的方法是一個原生態(tài)方法键闺,方法對應(yīng)的實現(xiàn)不是在當(dāng)前文件寿烟,而是在用其他語言(如C和C++)實現(xiàn)的文件中。Java語言本身不能對操作系統(tǒng)底層進行訪問和操作辛燥,但是可以通過JNI接口(Java Native Interfac)調(diào)用其他語言來實現(xiàn)對底層的訪問筛武。存在的必要:需要與java外的環(huán)境做交互,與jvm,操作系統(tǒng)交互得到更多的特性挎塌,sun的解釋器是C實現(xiàn)的,實現(xiàn)更好的交互徘六。

  1. 標識符native可以與所有其它的java標識符連用,但是abstract除外
  2. 一個native method方法可以返回任何java類型榴都,包括非基本類型待锈,而且同樣可以進行異常控制嘴高。
  3. 使用本地方法是有開銷的

**JVM怎樣使Native Method跑起來: **

當(dāng)一個類第一次被使用到時竿音,這個類的字節(jié)碼會被加載到內(nèi)存,并且只會回載一次拴驮。在這個被加載的字節(jié)碼的入口維持著一個該類所有方法描述符的list春瞬,這些方法描述符包含這樣一些信息:方法代碼存于何處,它有哪些參數(shù)莹汤,方法的描述符(public之類)等等快鱼。

如果一個方法描述符內(nèi)有native,這個描述符塊將有一個指向該方法的實現(xiàn)的指針纲岭。這些實現(xiàn)在一些DLL文件內(nèi),但是它們會被操作系統(tǒng)加載到j(luò)ava程序的地址空間线罕。當(dāng)一個帶有本地方法的類被加載時止潮,其相關(guān)的DLL并未被加載,因此指向方法實現(xiàn)的指針并不會被設(shè)置钞楼。當(dāng)本地方法被調(diào)用之前喇闸,這些DLL才會被加載,這是通過調(diào)用java.system.loadLibrary()實現(xiàn)的询件。

JNI的書寫步驟如下:

a.編寫帶有native聲明的方法的Java類

b.使用javac命令編譯編寫的Java類

c.使用java -jni ****來生成后綴名為.h的頭文件

d.使用其他語言(C燃乍、C++)實現(xiàn)本地方法

e.將本地方法編寫的文件生成動態(tài)鏈接庫

注:
1.在C++中,你可以用extern "C"告知C++編譯器去調(diào)用一個C的函數(shù)宛琅。
2.http://blog.csdn.net/wike163/article/details/6635321

3.偽共享##

偽共享(false sharing)刻蟹,就是多個線程同時修改共享在同一個緩存行里的獨立變量,無意中影響了性能嘿辟。

偽共享發(fā)生的過程

當(dāng)核心1上的線程想更新X舆瘪,而核心2上的線程想更新Y片效,而X變量和Y變量在同一個緩存行中時;每個線程都要去競爭緩存行的所有權(quán)來更新變量英古。如果核心1獲得所緩存行的所有權(quán)淀衣,那么緩存子系統(tǒng)將會使核心2中對應(yīng)的緩存行失效,反之亦然召调。這會來來回回的經(jīng)過L3緩存膨桥,大大影響了性能。這種情況唠叛,就像多個線程同事競爭鎖的所有權(quán)一樣只嚣。如果互相競爭的核心位于不同的插槽,就要額外橫跨插槽連接玻墅,問題可能更加嚴重介牙。

典型的CPU微架構(gòu)有3級緩存, 每個核都有自己私有的L1, L2緩存.

解決偽共享的方法是通過補齊(Padding),使得每一條緩存行只存一個多線程變量澳厢。

參考:
http://www.it165.net/pro/html/201403/11104.html
http://coderplay.iteye.com/blog/1486649

4.線程Dump文件##

Dump文件是進程的內(nèi)存鏡像环础。可以把程序的執(zhí)行狀態(tài)通過調(diào)試器保存到dump文件中剩拢。
Dump文件是用來給驅(qū)動程序編寫人員調(diào)試驅(qū)動程序用的线得,這種文件必須用專用工具軟件打開,比如使用WinDbg打開徐伐。

線程dump出來的信息包含線程基本信息贯钩;線程的運行狀態(tài)、標識和調(diào)用的堆棧办素;調(diào)用的堆棧包含完整的類名角雷,所執(zhí)行的方法,如果可能的話還有源代碼的行數(shù)性穿。因此勺三,可以使用線程Dump文件來進行診斷一些問題, 包括線程阻塞需曾,CPU 使用率過高吗坚,JVM Crash,堆內(nèi)存不足和類裝載等呆万。

輸出的方法:

win下商源,在啟動程序的控制臺里敲: Ctrl - Break,線程的 dump會產(chǎn)生在標準輸出中

Linux 下谋减,你可以通過命令 kill -3 PID (Java 進程的進程 ID)來獲取 Java 應(yīng)用的 dump 文件牡彻。

5.內(nèi)存溢出##

1.什么是內(nèi)存溢出

內(nèi)存溢出是指應(yīng)用系統(tǒng)中存在無法回收的內(nèi)存或使用的內(nèi)存過多,最終使得程序運行要用到的內(nèi)存大于虛擬機能提供的最大內(nèi)存。

jvm管理的內(nèi)存大致包括三種不同類型的內(nèi)存區(qū)域:Permanent Generation space(永久保存區(qū)域)逃顶、Heap space(堆區(qū)域)讨便、Java Stacks(Java棧)充甚。
永久保存區(qū)域主要存放Class(類)和Meta的信息,Class第一次被Load的時候被放入PermGen space區(qū)域霸褒,Class需要存儲的內(nèi)容主要包括方法和靜態(tài)屬性伴找。
堆區(qū)域用來存放Class的實例(即對象),對象需要存儲的內(nèi)容主要是非靜態(tài)屬性废菱。每次用new創(chuàng)建一個對象實例后技矮,對象實例存儲在堆區(qū)域中,這部分空間也被jvm的垃圾回收機制管理殊轴。
而Java棧跟大多數(shù)編程語言包括匯編語言的棧功能相似衰倦,主要基本類型變量以及方法的輸入輸出參數(shù)。Java程序的每個線程中都有一個獨立的堆棧旁理。容易發(fā)生內(nèi)存溢出問題的內(nèi)存空間包括:Permanent Generation space和Heap space樊零。

2.引起內(nèi)存溢出的主要原因

1.內(nèi)存中加載的數(shù)據(jù)量過于龐大,如一次從數(shù)據(jù)庫取出過多數(shù)據(jù)孽文;
2.集合類中有對對象的引用驻襟,使用完后未清空,使得JVM不能回收芋哭;
3.代碼中存在死循環(huán)或循環(huán)產(chǎn)生過多重復(fù)的對象實體沉衣;
4.使用的第三方軟件中的BUG;
5.啟動參數(shù)內(nèi)存值設(shè)定的過小

3.解決內(nèi)存溢出的方法

第一步减牺,修改JVM啟動參數(shù)豌习,直接增加內(nèi)存。(-Xms拔疚,-Xmx參數(shù)一定不要忘記加肥隆。)
第二步,檢查錯誤日志稚失,查看“OutOfMemory”錯誤前是否有其它異诚镉欤或錯誤。
第三步墩虹,對代碼進行走查和分析,找出可能發(fā)生內(nèi)存溢出的位置憨琳。

4.三種類型

** OutOfMemoryError: PermGen space**

發(fā)生這種問題的原意是程序中使用了大量的jar或class诫钓,使java虛擬機裝載類的空間不夠,與Permanent Generation space有關(guān)篙螟。解決這類問題有以下兩種辦法:

  1. 增加java虛擬機中的XX:PermSize和XX:MaxPermSize參數(shù)的大小菌湃,其中XX:PermSize是初始永久保存區(qū)域大小,XX:MaxPermSize是最大永久保存區(qū)域大小遍略。如針對tomcat6.0惧所,在catalina.sh 或catalina.bat文件中一系列環(huán)境變量名說明結(jié)束處(大約在70行左右) 增加一行:
    JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"

  2. 清理應(yīng)用程序中web-inf/lib下的jar骤坐,如果tomcat部署了多個應(yīng)用,很多應(yīng)用都使用了相同的jar下愈,可以將共同的jar移到tomcat共同的lib下纽绍,減少類的重復(fù)加載。

OutOfMemoryError: Java heap space

發(fā)生這種問題的原因是java虛擬機創(chuàng)建的對象太多势似,在進行垃圾回收之間拌夏,虛擬機分配的到堆內(nèi)存空間已經(jīng)用滿了,與Heap space有關(guān)履因。解決這類問題有兩種思路:

  1. 檢查程序障簿,看是否有死循環(huán)或不必要地重復(fù)創(chuàng)建大量對象。找到原因后栅迄,修改程序和算法站故。

  2. 增加Java虛擬機中Xms(初始堆大小)和Xmx(最大堆大幸阌摺)參數(shù)的大小西篓。如:set JAVA_OPTS= -Xms256m -Xmx1024m

OutOfMemoryError:unable to create new native thread

這種錯誤在Java線程個數(shù)很多的情況下容易發(fā)生。

6.jvm 配置和參數(shù)##

-Xms 初始堆大小
-Xmx 最大堆大小
-Xmn 年輕代大小
-Xss 每個線程的堆棧大小
-XX:參數(shù)

具體的內(nèi)容參照下面的引文吧朗兵。

堆分配

JVM初始分配的內(nèi)存由-Xms指定污淋,默認是物理內(nèi)存的1/64;JVM最大分配的內(nèi)存由-Xmx指定余掖,默認是物理內(nèi)存的1/4寸爆。默認空余堆內(nèi)存小于40%時,JVM就會增大堆直到-Xmx的最大限制盐欺;空余堆內(nèi)存大于70%時赁豆,JVM會減少堆直到 -Xms的最小限制。因此服務(wù)器一般設(shè)置-Xms冗美、-Xmx相等以避免在每次GC 后調(diào)整堆的大小魔种。
對象的堆內(nèi)存由稱為垃圾回收器的自動內(nèi)存管理系統(tǒng)回收。

堆分配

Eden:存放新生的對象
Survivor Space:有兩個粉洼,存放每次垃圾回收后存活的對象
Old Generation:主要存放應(yīng)用程序中生命周期長的存活對象

JVM(采用分代回收的策略)节预,用較高的頻率對年輕的對象(young generation)進行YGC,而對老對象(tenured generation)較少(tenured generation 滿了后才進行)進行Full GC属韧。這樣就不需要每次GC都將內(nèi)存中所有對象都檢查一遍安拟。

非堆內(nèi)存分配

JVM使用-XX:PermSize設(shè)置非堆內(nèi)存初始值,默認是物理內(nèi)存的1/64宵喂;由XX:MaxPermSize設(shè)置最大非堆內(nèi)存的大小糠赦,默認是物理內(nèi)存的1/4。

GC不會在主程序運行期對PermGen Space進行清理,所以如果你的應(yīng)用中有很多CLASS(特別是動態(tài)生成類拙泽,當(dāng)然permgen space存放的內(nèi)容不僅限于類)的話,就很可能出現(xiàn)PermGen Space錯誤淌山。

參考:
JVM性能優(yōu)化
JVM參數(shù)設(shè)置、分析
GC策略&內(nèi)存申請顾瞻、對象衰老
HotSpot VM GC 的種類

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泼疑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子朋其,更是在濱河造成了極大的恐慌王浴,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梅猿,死亡現(xiàn)場離奇詭異氓辣,居然都是意外死亡,警方通過查閱死者的電腦和手機袱蚓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門钞啸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喇潘,你說我怎么就攤上這事体斩。” “怎么了颖低?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵絮吵,是天一觀的道長。 經(jīng)常有香客問我忱屑,道長蹬敲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任莺戒,我火速辦了婚禮伴嗡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘从铲。我一直安慰自己瘪校,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布名段。 她就那樣靜靜地躺著阱扬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伸辟。 梳的紋絲不亂的頭發(fā)上价认,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音自娩,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛忙迁,可吹牛的內(nèi)容都是我干的脐彩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼姊扔,長吁一口氣:“原來是場噩夢啊……” “哼惠奸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起恰梢,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤佛南,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嵌言,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嗅回,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年摧茴,在試婚紗的時候發(fā)現(xiàn)自己被綠了绵载。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡苛白,死狀恐怖娃豹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情购裙,我是刑警寧澤懂版,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站躏率,受9級特大地震影響躯畴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜禾锤,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一私股、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恩掷,春花似錦倡鲸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逼争,卻和暖如春优床,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背誓焦。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工胆敞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓移层,卻偏偏與公主長得像仍翰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子观话,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容