亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

JVM 堆(heap)溢出案例

leejan97 / 823人閱讀

摘要:一說(shuō)明當(dāng)虛擬機(jī)申請(qǐng)不到內(nèi)存空間的時(shí)候,會(huì)報(bào)堆內(nèi)存溢出。記錄次數(shù)不讓進(jìn)程結(jié)束,便于使用分析工具來(lái)查看內(nèi)存情況使用的版本報(bào)錯(cuò)信息運(yùn)行結(jié)果表明,運(yùn)行到次時(shí),出現(xiàn)了堆內(nèi)存溢出。

一、說(shuō)明

當(dāng)虛擬機(jī)申請(qǐng)不到內(nèi)存空間的時(shí)候,會(huì)報(bào)堆內(nèi)存溢出: OutOfMemoryError:java heap space。

常見(jiàn)的原因:http://outofmemory.cn/c/java-...

我測(cè)試到時(shí)候,運(yùn)行在 16G 內(nèi)存的機(jī)器上。JVM 堆內(nèi)存 默認(rèn)為物理內(nèi)存的1/4,即 16 * 1/4 = 4G

JDK 8的 JVM 在 JDK 7 的基礎(chǔ)上從堆內(nèi)存中移除了永久代(Perm Generation),替換為了堆內(nèi)存之外的元空間(Metaspace),元空間是堆外直接內(nèi)存,不受堆內(nèi)存的限制,只受物理內(nèi)存的限制,可以提供更大的空間。
二、原因及解決辦法

OutOfMemoryError 異常的常見(jiàn)原因:

加載的數(shù)據(jù)過(guò)大。如:加載的文件或者圖片過(guò)大、一次從數(shù)據(jù)庫(kù)取出過(guò)多數(shù)據(jù)

代碼存在死循環(huán)或循環(huán)產(chǎn)生過(guò)多的對(duì)象

解決方法

增加jvm的內(nèi)存大小,使用 -Xmx 和 -Xms 來(lái)設(shè)置

檢查代碼中是否有死循環(huán)或遞歸調(diào)用。

檢查是否有大循環(huán)重復(fù)產(chǎn)生新對(duì)象實(shí)體。

檢查對(duì)數(shù)據(jù)庫(kù)查詢(xún)中,是否有一次獲得全部數(shù)據(jù)的查詢(xún)。一般來(lái)說(shuō),如果一次取十萬(wàn)條記錄到內(nèi)存,就可能引起內(nèi)存溢出。這個(gè)問(wèn)題比較隱蔽,在上線(xiàn)前,數(shù)據(jù)庫(kù)中數(shù)據(jù)較少,不容易出問(wèn)題,上線(xiàn)后,數(shù)據(jù)庫(kù)中數(shù)據(jù)多了,一次查詢(xún)就有可能引起內(nèi)存溢出。因此對(duì)于數(shù)據(jù)庫(kù)查詢(xún)盡量采用分頁(yè)的方式查詢(xún)。

檢查L(zhǎng)ist、Map等集合對(duì)象是否有使用完后,未清除的問(wèn)題。List、MAP等集合對(duì)象會(huì)始終存有對(duì)對(duì)象的引用,使得這些對(duì)象不能被GC回收。

三、代碼示例
/**java堆溢出實(shí)例
 * 原理:java的堆是用來(lái)存放對(duì)象實(shí)例的,所以我們只要做到以下三點(diǎn)就可以使堆溢出:
 * 1、限制堆的大小,不可擴(kuò)展
 * 2、不斷新建對(duì)象
 * 3、保持對(duì)象存活不被回收
 * 對(duì)應(yīng)的,我們需要:
 * 1、改變JVM的啟動(dòng)參數(shù),將堆的最小值和最大值設(shè)成一樣,這樣就可以避免堆自動(dòng)擴(kuò)展(其實(shí)不一樣也可以)
 * 2、不斷產(chǎn)生對(duì)象
 * 3、使用一個(gè)List來(lái)保存對(duì)象,保持對(duì)象存活
 *
 * JVM配置參數(shù): -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
 *
 */
public class HeapOom {
    public static void main(String[] args) {
        // 此list實(shí)例會(huì)存放在堆內(nèi)存中
        List list = new ArrayList<>();
        int i = 0;
        boolean flag = true;
        while (flag) {
            try {
                i++;
                // 每次增加一個(gè)1M大小的數(shù)組對(duì)象
                list.add(new byte[1024 * 1024]);
            } catch (Throwable e) {  // catch 捕獲的是 Throwable,而不是 Exception。因?yàn)?OutOfMemoryError 不屬于 Exception 的子類(lèi)。
                e.printStackTrace();
                flag = false;
                // 記錄次數(shù)
                System.out.println("count=" + i);
            }
        }

        // 不讓進(jìn)程結(jié)束,便于使用分析工具來(lái)查看內(nèi)存情況
        try {
            Thread.sleep(24 * 60 * 60 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

使用的 java 1.8.0_171 版本:

$ java -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

報(bào)錯(cuò)信息:

count=3316
java.lang.OutOfMemoryError: Java heap space
    at com.song.HeapOom.main(HeapOom.java:21)

運(yùn)行結(jié)果表明,運(yùn)行到 3316 次時(shí),出現(xiàn)了堆內(nèi)存溢出。由于每次增加1M內(nèi)存。粗略估計(jì):程序大約使用3G內(nèi)存時(shí),出現(xiàn)了內(nèi)存溢出情況。

通過(guò)jmap或VisualVM 者工具可以查看內(nèi)存情況:最后可以看出,老年代內(nèi)存使用情況,大約使用了2709MB,使用率近100%。從而導(dǎo)致了 OutOfMemoryError

TIPS:下面查看內(nèi)存時(shí),由于使用工具查看內(nèi)存的時(shí)間不是同一時(shí)間,所以?xún)?nèi)存使用量有細(xì)微差別
1. 使用jmap查看的內(nèi)存信息
$ jmap -heap 3428
Attaching to process ID 3428, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.66-b18

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 4261412864 (4064.0MB)
   NewSize                  = 88604672 (84.5MB)
   MaxNewSize               = 1420296192 (1354.5MB)
   OldSize                  = 177733632 (169.5MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 637009920 (607.5MB)
   used     = 637009920 (607.5MB)
   free     = 0 (0.0MB)
   100.0% used
From Space:
   capacity = 11010048 (10.5MB)
   used     = 0 (0.0MB)
   free     = 11010048 (10.5MB)
   0.0% used
To Space:
   capacity = 11010048 (10.5MB)
   used     = 0 (0.0MB)
   free     = 11010048 (10.5MB)
   0.0% used
PS Old Generation  // 老年代內(nèi)存使用情況,大約使用了2709MB,使用率近100%(導(dǎo)致OutOfMemoryError)
   capacity = 2841116672 (2709.5MB)
   used     = 2840991320 (2709.38045501709MB)
   free     = 125352 (0.11954498291015625MB)
   99.99558793198338% used

4955 interned Strings occupying 422328 bytes.

2. 使用 VisualVM 查看的內(nèi)存信息

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/75094.html

相關(guān)文章

  • 關(guān)于JVM內(nèi)存溢出的原因分析及解決方案探討

    摘要:內(nèi)存溢出分配的內(nèi)存空間超過(guò)系統(tǒng)內(nèi)存。內(nèi)存泄漏的原因分析由大塊組成堆,棧,本地方法棧,程序計(jì)數(shù)器,方法區(qū)。內(nèi)存溢出的原因分析內(nèi)存溢出是由于沒(méi)被引用的對(duì)象垃圾過(guò)多造成沒(méi)有及時(shí)回收,造成的內(nèi)存溢出。小結(jié)棧內(nèi)存溢出程序所要求的棧深度過(guò)大導(dǎo)致。 showImg(https://segmentfault.com/img/bVbweuq?w=563&h=300); 前言:JVM中除了程序計(jì)數(shù)器,其他...

    xuexiangjys 評(píng)論0 收藏0
  • 十種JVM內(nèi)存溢出的情況,你碰到過(guò)幾種?

    摘要:內(nèi)存溢出的情況就是從類(lèi)加載器加載的時(shí)候開(kāi)始出現(xiàn)的,內(nèi)存溢出分為兩大類(lèi)和。以下舉出個(gè)內(nèi)存溢出的情況,并通過(guò)實(shí)例代碼的方式講解了是如何出現(xiàn)內(nèi)存溢出的。內(nèi)存溢出問(wèn)題描述元空間的溢出,系統(tǒng)會(huì)拋出。這樣就會(huì)造成棧的內(nèi)存溢出。 導(dǎo)言: 對(duì)于java程序員來(lái)說(shuō),在虛擬機(jī)自動(dòng)內(nèi)存管理機(jī)制的幫助下,不需要自己實(shí)現(xiàn)釋放內(nèi)存,不容易出現(xiàn)內(nèi)存泄漏和內(nèi)存溢出的問(wèn)題,由虛擬機(jī)管理內(nèi)存這一切看起來(lái)非常美好,但是一旦...

    ShevaKuilin 評(píng)論0 收藏0
  • 摘記《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第2版)》

    摘要:第章內(nèi)存區(qū)域與內(nèi)存溢出異常運(yùn)行時(shí)數(shù)據(jù)區(qū)域虛擬機(jī)在執(zhí)行程序的過(guò)程中會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域。即對(duì)象指向它的類(lèi)元數(shù)據(jù)的指針,虛擬機(jī)通過(guò)這個(gè)指針來(lái)確定這個(gè)對(duì)象是哪個(gè)類(lèi)的實(shí)例。 第2章 Java內(nèi)存區(qū)域與內(nèi)存溢出異常 2.2 運(yùn)行時(shí)數(shù)據(jù)區(qū)域 Java虛擬機(jī)在執(zhí)行Java程序的過(guò)程中會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域。根據(jù)《Java虛擬機(jī)規(guī)范(Java SE 7版)...

    zoomdong 評(píng)論0 收藏0
  • 【修煉內(nèi)功】[JVM] 淺談虛擬機(jī)內(nèi)存模型

    摘要:也正是因此,一旦出現(xiàn)內(nèi)存泄漏或溢出問(wèn)題,如果不了解的內(nèi)存管理原理,那么將會(huì)對(duì)問(wèn)題的排查帶來(lái)極大的困難。 本文已收錄【修煉內(nèi)功】躍遷之路 showImg(https://segmentfault.com/img/bVbsP9I?w=1024&h=580); 不論做技術(shù)還是做業(yè)務(wù),對(duì)于Java開(kāi)發(fā)人員來(lái)講,理解JVM各種原理的重要性不必再多言 對(duì)于C/C++而言,可以輕易地操作任意地址的...

    sanyang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<