程序小白在寫代碼的過程中,經(jīng)常會不經(jīng)意間寫出發(fā)生內(nèi)存溢出異常的代碼。很多時候這類異常如何產(chǎn)生的都傻傻弄不清楚,如果能故意寫出讓jvm發(fā)生內(nèi)存溢出的代碼,有時候看來也并非一件容易的事。最近通過學(xué)習(xí)《深入理解java虛擬機(jī)-JVM高級特性與最佳實(shí)踐》這本書,終于初步了解了一下java虛擬機(jī)的內(nèi)存模型。本文通過寫出使jvm發(fā)生內(nèi)存溢出異常的代碼來對自己的學(xué)習(xí)結(jié)果進(jìn)行總結(jié),同時也提醒自己以后寫代碼時候不要再跳進(jìn)這個坑啦。

java的內(nèi)存管理是由java虛擬機(jī)自動進(jìn)行管理的,并不需要程序員過多的手動干預(yù),這也就導(dǎo)致了初學(xué)java的人在不了解java內(nèi)存模型的情況下也能愉快的進(jìn)行coding。不過一旦涉及了內(nèi)存泄露或者內(nèi)存溢出以及垃圾回收(GC)方面的問題,如果不了解虛擬機(jī)是怎么管理內(nèi)存的,那么排查問題,定位錯誤地點(diǎn)就顯得無從下手了。首先上圖看一下java虛擬機(jī)運(yùn)行時數(shù)據(jù)區(qū)是什么樣子(圖片來源于網(wǎng)絡(luò)):

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計(jì)算培訓(xùn),高端軟件開發(fā)培訓(xùn),項(xiàng)目經(jīng)理培訓(xùn)

從上圖我們可以獲得以下信息:

  1. jvm內(nèi)存分區(qū)可以分為所有線程共享數(shù)據(jù)區(qū)以及線程隔離數(shù)據(jù)區(qū)兩部分。這也就是說圖中的方法區(qū)和堆是由所有的線程共同使用的,而虛擬機(jī)棧、本地方法棧、程序計(jì)數(shù)器則是每個線程獨(dú)有各自的響應(yīng)數(shù)據(jù)區(qū),各線程之間是互不干擾的。

  2. jvm運(yùn)行時數(shù)據(jù)區(qū)按照功能可分為方法區(qū),堆,虛擬機(jī)棧,本地方法棧,程序計(jì)數(shù)器五個部分。各個部分存儲的數(shù)據(jù)類型不同。 

本文主要講述如何讓JVM發(fā)生內(nèi)存溢出異常,有關(guān)JVM內(nèi)存模型將會在另一篇文章中詳細(xì)講解,這里簡單介紹各分區(qū)的作用:

  1. 堆:各線程共享;存放java對象實(shí)例,以及為數(shù)組分配的空間也在此處

  2. 虛擬機(jī)棧:線程私有;生命周期與線程相同,描述java方法執(zhí)行的內(nèi)存模型,每個方法在執(zhí)行時創(chuàng)建棧幀,棧幀存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、返回地址(方法出口)等信息

  3. 本地方法棧:和虛擬機(jī)棧功能類似,線程私有;為虛擬機(jī)使用的Native方法提供服務(wù)

  4. 方法區(qū):各線程共享;存儲已被虛擬機(jī)加載的類的信息、final聲明的常量,static修飾的靜態(tài)變量,以及編譯器編譯后的java代碼等數(shù)據(jù)(jdk7以后把常量池移到了堆中

  5. 程序計(jì)數(shù)器:線程私有;可以看做是當(dāng)前線程所執(zhí)行程序的字節(jié)碼的行號指示器

在jvm規(guī)范中,除了程序計(jì)數(shù)器內(nèi)存區(qū)域沒有規(guī)定任何內(nèi)存溢出異常情形外,其他四個內(nèi)存區(qū)域都會有相應(yīng)的內(nèi)存溢出異常發(fā)生的可能,所以jvm內(nèi)存溢出異常發(fā)生在不同的內(nèi)存區(qū)域具有不同的異常發(fā)生原因,知道一內(nèi)存異常產(chǎn)生的位置,對于定位錯誤地點(diǎn)就很有指向性了。

下面就通過實(shí)例來展示,如何通過代碼指定讓不同的內(nèi)存區(qū)域發(fā)生內(nèi)存溢出異常。

一、java堆發(fā)生內(nèi)存溢出:

java堆是用來存儲對象實(shí)例以及數(shù)組的,使java堆發(fā)生內(nèi)存溢出的要旨是:

  • 不斷創(chuàng)建對象

  • 保證對象存活,不會被垃圾收集器回收

java虛擬機(jī)的內(nèi)存大小是可以人為設(shè)置的,通過設(shè)置限制內(nèi)存大小,可以很方便的實(shí)現(xiàn)內(nèi)存溢出,節(jié)約了時間。

設(shè)置java堆內(nèi)存大小的虛擬機(jī)參數(shù)為:-Xms堆的初始大小 -Xmx堆可擴(kuò)展的最大值

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計(jì)算培訓(xùn),高端軟件開發(fā)培訓(xùn),項(xiàng)目經(jīng)理培訓(xùn) 

網(wǎng)友評論