成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

程序內(nèi)存溢出問題分析

IT那活兒 / 1923人閱讀
程序內(nèi)存溢出問題分析
點(diǎn)擊上方“IT那活兒”,關(guān)注后了解更多內(nèi)容,不管IT什么活兒,干就完了!??!





場景來源




戶現(xiàn)場有一套重要的業(yè)務(wù)系統(tǒng),供業(yè)務(wù)同事進(jìn)行使用,但是每連續(xù)運(yùn)行10天都會(huì)出現(xiàn)問題,會(huì)造成程序慢響應(yīng),無響應(yīng)情況,嚴(yán)重影響消費(fèi)者、使用者的使用體驗(yàn),經(jīng)常得到業(yè)務(wù)同事反饋,所以配合研發(fā)對該問題進(jìn)行查詢。


該系統(tǒng)硬件服務(wù)器性能足夠,但每個(gè)重啟周期內(nèi)內(nèi)存都是緩慢上升,觀察JVM使用率、系統(tǒng)內(nèi)存使用率等均是持續(xù)上升,未發(fā)現(xiàn)有主動(dòng)進(jìn)行內(nèi)存回收,初步懷疑為內(nèi)存泄漏導(dǎo)致。






初識(shí)JVM虛擬機(jī)



Java語言是一種計(jì)算機(jī)編程語言,擁有跨平臺(tái),面向?qū)ο?,泛型編程的特性,廣泛應(yīng)用于企業(yè)級Web應(yīng)用的開發(fā)和移動(dòng)應(yīng)用的開發(fā)。
JVM是Java Virtual Machine(Java虛擬機(jī))的縮寫,JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來的計(jì)算機(jī),是通過在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來實(shí)現(xiàn)的。
引入Java語言虛擬機(jī)后,Java語言在不同平臺(tái)上運(yùn)行時(shí)不需要重新編譯。Java語言使用Java虛擬機(jī)屏蔽了與具體平臺(tái)相關(guān)的信息,使得Java語言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。
Java程序是如何實(shí)現(xiàn)跨平臺(tái)運(yùn)行的呢?
主要就是通過JVM虛擬機(jī)來運(yùn)行的。





JVM虛擬機(jī)的結(jié)構(gòu)




Java虛擬機(jī)主要分為五大模塊:


  • 類裝載器子系統(tǒng)
  • 運(yùn)行時(shí)數(shù)據(jù)區(qū)
  • 執(zhí)行引擎
  • 本地方法接口
  • 垃圾收集模塊
其中垃圾收集模塊在Java虛擬機(jī)規(guī)范中并沒有要求Java虛擬機(jī)垃圾收集,但是在沒有發(fā)明無限的內(nèi)存之前,大多數(shù)JVM實(shí)現(xiàn)都是有垃圾收集的。而運(yùn)行時(shí)數(shù)據(jù)區(qū)都會(huì)以某種形式存在于每一個(gè)JAVA虛擬機(jī)實(shí)例中,但是Java虛擬機(jī)規(guī)范對它的描述卻是相當(dāng)抽象。
這些運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)上的細(xì)節(jié),大多數(shù)都由具體實(shí)現(xiàn)的設(shè)計(jì)者決定。
當(dāng)我們程序運(yùn)行后會(huì)申請內(nèi)存空間,其中java棧本地方法棧,程序計(jì)算器是JVM虛擬機(jī)自動(dòng)管理的,我們可以管理的區(qū)域是堆區(qū)和方法區(qū),經(jīng)常說的java內(nèi)存調(diào)優(yōu)調(diào)的就是這兩個(gè)區(qū)域。




常見的內(nèi)存溢出




現(xiàn)象一:


java.lang.OutOfMemoryError: Java heap space
該報(bào)錯(cuò)為堆溢出,這種場景最為常見主要原因可能有:
  • 代碼中可能存在大對象分配。

  • 可能存在內(nèi)存泄露,導(dǎo)致在多次GC之后,還是無法找到一塊足夠大的內(nèi)存容納當(dāng)前對象。

解決方法:
  • 檢查是否存在大對象的分配,最有可能的是大數(shù)組分配。

  • 如果沒有找到明顯的內(nèi)存泄露,可以臨時(shí) -Xmx 加大堆內(nèi)存。

  • 還有一點(diǎn)容易被忽略,檢查是否有大量的自定義的 Finalizable 對象,也有可能是框架內(nèi)部提供的,考慮其存在的必要性。

現(xiàn)象二:

java.lang.OutOfMemoryError: PermGen 
spacejava.lang.OutOfMemoryError: Metaspace
永久代是 HotSot 虛擬機(jī)對方法區(qū)的具體實(shí)現(xiàn),存放了被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、JIT編譯后的代碼等。
JDK8后,元空間替換了永久代,元空間使用的是本地內(nèi)存。該報(bào)錯(cuò)為永久代/元空間溢出,可能原因有如下幾種:
  • 在Java7之前,頻繁的錯(cuò)誤使用String.intern()方法 。

  • 運(yùn)行期間生成了大量的代理類,導(dǎo)致方法區(qū)被撐爆,無法卸載 。

  • 應(yīng)用長時(shí)間運(yùn)行,沒有重啟。

解決方法:
  • 檢查是否永久代空間或者元空間設(shè)置的過小。

  • 檢查代碼中是否存在大量的反射操作 。

  • dump之后通過mat檢查是否存在大量由于反射生成的代理類。

現(xiàn)象三:

java.lang.OutOfMemoryErrorGC overhead limit exceeded
這是JDK6新加的錯(cuò)誤類型,一般都是堆太小導(dǎo)致的。
Sun 官方對此的定義:超過98%的時(shí)間用來做GC并且回收了不到2%的堆內(nèi)存時(shí)會(huì)拋出此異常。
解決方法:
  • 檢查項(xiàng)目中是否有大量的死循環(huán)或有使用大內(nèi)存的代碼,優(yōu)化代碼。

  • 添加參數(shù) -XX:-UseGCOverheadLimit  禁用這個(gè)檢查,其實(shí)這個(gè)參數(shù)解決不了內(nèi)存問題,只是把錯(cuò)誤的信息延后,最終出現(xiàn) java.lang.OutOfMemoryError: Java heap space。

現(xiàn)象四:

java.lang.OutOfMemoryError : unable to create new native Thread


出現(xiàn)這種異常,基本上都是創(chuàng)建的了大量的線程導(dǎo)致的,以前碰到過一次,通過jstack出來一共8000多個(gè)線程。

解決方法:
  • 通過 -Xss 降低的每個(gè)線程棧大小的容量。

  • 線程總數(shù)也受到系統(tǒng)空閑內(nèi)存和操作系統(tǒng)的限制,檢查是否該系統(tǒng)下有此限制:

/proc/sys/kernel/pid_max
    /proc/sys/kernel/thread-max
    maxuserprocess(ulimit -u
    /proc/sys/vm/maxmapcount
現(xiàn)象五:
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
這種情況一般是由于不合理的數(shù)組分配請求導(dǎo)致的,在為數(shù)組分配內(nèi)存之前,JVM 會(huì)執(zhí)行一項(xiàng)檢查。要分配的數(shù)組在該平臺(tái)是否可以尋址(addressable),如果不能尋址(addressable)就會(huì)拋出這個(gè)錯(cuò)誤。
解決方法:
檢查你的代碼中是否有創(chuàng)建超大數(shù)組的地方。
現(xiàn)象六:
java.lang.OutOfMemoryError: Out of swap space
這種情況一般是操作系統(tǒng)導(dǎo)致的,可能的原因有:
  • swap 分區(qū)大小分配不足。

  • 其他進(jìn)程消耗了所有的內(nèi)存。

解決方案:
  • 其它服務(wù)進(jìn)程可以選擇性的拆分出去 。

  • 加大swap分區(qū)大小,或者加大機(jī)器內(nèi)存大小。





緊急處理方法



程序掛掉運(yùn)維層面可以從系統(tǒng)message日志中查看是否有OOM殺掉進(jìn)程報(bào)錯(cuò);如果有第一現(xiàn)場,在條件允許的情況下,可以dump內(nèi)存使用情況,通過工具分析可以更直觀的了解內(nèi)存具體使用到了那些地方。
當(dāng)然,如果能確認(rèn)為內(nèi)存溢出情況,萬能重啟大法可以先臨時(shí)解決供業(yè)務(wù)恢復(fù),等代碼修復(fù)上線后再從根本上修復(fù)問題。



本文作者:臧二飛

本文來源:IT那活兒(上海新炬王翦團(tuán)隊(duì))

???

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/129551.html

相關(guān)文章

  • JVM問題情景分析

    摘要:問題分析之死鎖產(chǎn)生死鎖必須同時(shí)滿足以下四個(gè)條件互斥條件一段時(shí)間內(nèi)某資源只能被一個(gè)線程進(jìn)程占有,若有其他請求線程只能等待。問題分析之內(nèi)存泄露內(nèi)存溢出堆內(nèi)存溢出內(nèi)存泄露指的是申請內(nèi)存后無法釋放該內(nèi)存。 問題分析之死鎖 產(chǎn)生死鎖必須同時(shí)滿足以下四個(gè)條件: 互斥條件:一段時(shí)間內(nèi)某資源只能被一個(gè)線程(進(jìn)程)占有,若有其他請求線程只能等待。 不剝奪條件:一個(gè)線程占用某資源后只能該線程自己釋放資...

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

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

    xuexiangjys 評論0 收藏0
  • Java內(nèi)存溢出(OutOfMemoryError)

    摘要:那就只能是處理的數(shù)據(jù)超過了堆區(qū)內(nèi)存上限,按照這個(gè)猜測往下分析。主要暴增對象如上圖框出來的地方。符合對象內(nèi)存一篇文中分析的字節(jié)大小。優(yōu)化自己的程序,使其在運(yùn)行過程中占用內(nèi)存盡可能的少。針對異常的具體優(yōu)化措施。 前言 在正式開始講解關(guān)于OutOfMemoryError錯(cuò)誤之前先來了解下,我在遇到這個(gè)異常的背景。 對數(shù)據(jù)充滿敬畏之心 我需要對hive中的數(shù)據(jù)進(jìn)行批量操作處理,對于沒有了解過h...

    calx 評論0 收藏0
  • Java 內(nèi)存結(jié)構(gòu)備忘錄

    摘要:本文詳細(xì)描述了堆內(nèi)存模型,垃圾回收算法以及處理內(nèi)存泄露的最佳方案,并輔之以圖表,希望能對理解內(nèi)存結(jié)構(gòu)有所幫助。該區(qū)域也稱為內(nèi)存模型的本地區(qū)。在中,內(nèi)存泄露是指對象已不再使用,但垃圾回收未能將他們視做不使用對象予以回收。 本文詳細(xì)描述了 Java 堆內(nèi)存模型,垃圾回收算法以及處理內(nèi)存泄露的最佳方案,并輔之以圖表,希望能對理解 Java 內(nèi)存結(jié)構(gòu)有所幫助。原文作者 Sumith Puri,...

    wow_worktile 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<