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

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

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

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

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

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

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

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

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

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

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

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

在jvm規(guī)范中,除了程序計數(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)生的位置,對于定位錯誤地點就很有指向性了。

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

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

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

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

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

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

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

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

延伸閱讀

學(xué)習(xí)是年輕人改變自己的最好方式-Java培訓(xùn),做最負責(zé)任的教育,學(xué)習(xí)改變命運,軟件學(xué)習(xí),再就業(yè),大學(xué)生如何就業(yè),幫大學(xué)生找到好工作,lphotoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)學(xué)習(xí)是年輕人改變自己的最好方式