国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java內(nèi)存溢出(OutOfMemoryError)

calx / 602人閱讀

摘要:那就只能是處理的數(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)行批量操作處理,對于沒有了解過hive的同學(xué)來說,有點(diǎn)茫然了。于是按照常規(guī)思路開始通過JDBC連接Hive讀取數(shù)據(jù) -> 處理數(shù)據(jù) -> 寫入數(shù)據(jù)。

貌似沒有什么不妥的,于是乎噼里啪啦代碼寫好了 -> 調(diào)試 -> 驗(yàn)證 -> 上線批量處理數(shù)據(jù)。上線處理數(shù)據(jù)的過程出問題了,為什么半天沒有處理完一條數(shù)據(jù)?

被坑了,Hive可不是MySQL能夠在ms內(nèi)返回結(jié)果給你,這下傻了,處理一條數(shù)據(jù)需要幾分鐘到十幾分鐘不等,簡直不能忍啊

不能忍了能怎么辦,能怎么辦優(yōu)化解決方案唄。而是借助Hive分布式MR的能力將輸入數(shù)據(jù)先處理一遍按照讀取的順序給整理好存放到中間表 -> 批量操作中間表 -> 數(shù)據(jù)寫回。

開始接近了本篇要講解的主題了,進(jìn)行批量操作數(shù)據(jù)而導(dǎo)致OutOfMemoryError。

為什么會出現(xiàn)OutOfMemoryError

相信有一定編程經(jīng)驗(yàn)的開發(fā)人員都會遇到這個(gè)錯(cuò)誤,其實(shí)出現(xiàn)這個(gè)錯(cuò)誤大家肯定想到的原因:是不是程序?qū)懙挠袉栴}產(chǎn)生了大量垃圾對象沒法被JVM回收掉,亦或者是程序的正常邏輯確實(shí)需要用到比JVM提供的堆區(qū)內(nèi)存大。

本人在遇到這個(gè)錯(cuò)誤的時(shí)候也是這么懷疑過,于是首先去檢查了下自己的代碼,因?yàn)檫壿嫶a比較少仔細(xì)分析后發(fā)現(xiàn)程序?qū)懙臎]問題,不應(yīng)該出現(xiàn)無法被JVM回收的內(nèi)存垃圾。那怎么驗(yàn)證自己的代碼沒有出現(xiàn)內(nèi)存垃圾?

通過 jmap -histo:live 可以分析出所有存活的對象所占用的內(nèi)存大小。

?

發(fā)現(xiàn)在跳出批量處理數(shù)據(jù)的邏輯后,所有相關(guān)的內(nèi)存都被回收了,所以確認(rèn)沒有內(nèi)存垃圾。

那就只能是處理的數(shù)據(jù)超過了JVM堆區(qū)內(nèi)存上限,按照這個(gè)猜測往下分析。

首先來觀察下機(jī)器內(nèi)存的變化情況jstat -gc 5000 100 后面兩個(gè)參數(shù)一個(gè)是間隔多久統(tǒng)計(jì)一次,總共統(tǒng)計(jì)多少次。不了解可以自行搜索資料了解這個(gè)命令的輸出參數(shù)。

?

確實(shí)內(nèi)存會在一段時(shí)間后大量釋放,然后隨著運(yùn)行又將整個(gè)堆區(qū)給占滿了。到這里可以確定是由于批量處理數(shù)據(jù)太多而使線程所擁有的堆區(qū)撐爆了。

本來分析應(yīng)該到這里為止了,但是得知道是什么將堆區(qū)給占滿了吧?

什么將內(nèi)存給占滿了

首先通過Java對象內(nèi)存存儲結(jié)構(gòu)這篇文章了解Java一個(gè)對象在內(nèi)存中分配的字節(jié)數(shù)為多少。

通過jmap -histo:live 查看在內(nèi)存滿和不滿的時(shí)候其中存活的對象。

?

主要暴增對象如上圖框出來的地方。

TestObject定義如下:

public class TestObject {

    private String a;

    private String b;

    private String c;

    private String d;

    private Integer e;

    private Integer f;
}

從TestObject的定義和上圖存活對象的對比就可以判斷出java.lang.String、java.lang.Integer、[C暴增的原因了。

TestObject size = 194664000/4866600 = 40

String size = 514238640/21426610 = 24

符合Java對象內(nèi)存一篇文中分析的字節(jié)大小。

JVM內(nèi)存波動

JVM內(nèi)存管理很多前輩都已經(jīng)講的非常清楚了,根據(jù)理論我們來實(shí)際窺探下JVM是如何針對內(nèi)存進(jìn)行管理的,同時(shí)如何進(jìn)行內(nèi)存回收。

?

根據(jù)JVM對內(nèi)存的使用策略我們可以看到程序不斷使用內(nèi)存的過程中堆內(nèi)存容量在各個(gè)部分的波動情況,在新生代/老生代內(nèi)存達(dá)到一定百分比的同時(shí)GC回收的回收情況。

觸發(fā)條件:
老生代:1043574/1329152 = 0.78 (-XX:CMSInitiatingOccupancyFraction 參數(shù)控制容量達(dá)到多少進(jìn)行FGC)
新生代:在Eden區(qū)滿后觸發(fā)

總結(jié)

針對OutOfMemoryError優(yōu)化手段無非兩種:

加大堆區(qū)內(nèi)存。

優(yōu)化自己的程序,使其在運(yùn)行過程中占用內(nèi)存盡可能的少。

針對OutOfMemoryError異常的具體優(yōu)化措施。

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/67527.html

相關(guān)文章

  • Java內(nèi)存區(qū)域及內(nèi)存溢出

    摘要:直接通過可以造成本機(jī)內(nèi)存溢出。小節(jié)內(nèi)存區(qū)域描述異常程序計(jì)數(shù)器略略略虛擬機(jī)棧存放編譯器可知的各種基本類型,對象引用和類型每個(gè)線程的棧大小堆存放對象實(shí)例最大值最小值運(yùn)行時(shí)常亮池存放編譯期生成的字面量和符號引用,運(yùn)行期也能放入常量池。 堆溢出 Java堆用于存儲對象實(shí)例,只要不斷地創(chuàng)建對象,并且保證GC Roots到對象之間有可達(dá)路徑避免垃圾回收,當(dāng)?shù)竭_(dá)最大堆的容量限制后就會產(chǎn)生Java.l...

    cheukyin 評論0 收藏0
  • Java 常見內(nèi)存溢出異常與代碼實(shí)現(xiàn)

    摘要:堆堆是用來存儲對象實(shí)例的因此如果我們不斷地創(chuàng)建對象并且保證和創(chuàng)建的對象之間有可達(dá)路徑以免對象被垃圾回收那么當(dāng)創(chuàng)建的對象過多時(shí)會導(dǎo)致內(nèi)存不足進(jìn)而引發(fā)異常上面是一個(gè)引發(fā)異常的代碼我們可以看到它就是通過不斷地創(chuàng)建對象并將對象保存在中防止其被 Java 堆 OutOfMemoryError Java 堆是用來存儲對象實(shí)例的, 因此如果我們不斷地創(chuàng)建對象, 并且保證 GC Root 和創(chuàng)建的對象...

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

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

    sanyang 評論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
  • 十種JVM內(nèi)存溢出的情況,你碰到過幾種?

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

    ShevaKuilin 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<