更新時(shí)間:2022-04-21 10:59:24 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1174次
JVM創(chuàng)建者在設(shè)計(jì)它時(shí)考慮了自動(dòng)內(nèi)存管理,這意味著程序員不需要擔(dān)心內(nèi)存分配和內(nèi)存。未使用的對(duì)象可以以透明的方式自動(dòng)釋放,這非常方便,尤其是當(dāng)您剛接觸JVM時(shí)。但是,即使是一般情況下,要編寫的代碼也比傳統(tǒng)方法少,而且不容易出錯(cuò),因?yàn)閭鹘y(tǒng)方法要求您手動(dòng)執(zhí)行所有操作。
然而,實(shí)際情況并不像聽(tīng)起來(lái)那么理想,尤其是當(dāng)你在開(kāi)發(fā)具有巨大流量的長(zhǎng)壽命應(yīng)用程序時(shí)。雖然在JVM中引起內(nèi)存泄漏比在C中更難,但仍然有可能。選擇GC算法并將其參數(shù)化對(duì)性能也有很大的影響。而且,與任何抽象或自動(dòng)化一樣,如果您希望有意識(shí)地編寫代碼(這是專業(yè)的方法),您需要了解在幕后進(jìn)行了哪些工作,以便能夠預(yù)防或診斷問(wèn)題。讓我們來(lái)看看一些有用的工具和技術(shù),這些工具和技術(shù)將幫助您找到應(yīng)用程序崩潰或減速的原因,而不是快速工作并能夠完成創(chuàng)建它的目的。
我們需要的第一件事是一段導(dǎo)致OutOfMemoryError的可靠代碼。OutOfMemoryError是JVM引發(fā)的異常,它通知我們內(nèi)存不足。可能有許多可能的原因?qū)е聮伋龃水惓#梢圆榭串惓5脑蛞粤私獍l(fā)生了什么。現(xiàn)在,讓我們編寫一個(gè)應(yīng)用程序,它會(huì)不斷地分配內(nèi)存,直到超過(guò)內(nèi)存限制為止;
// file Application.scala
object Application {
def main(args: Array[String]): Unit = {
LazyList.from(0).toList
}
}
編譯一下:
scalac Application.scala
設(shè)置堆大小:
scala Application -J-Xmx10m -J-Xms10m
Xms和Xmx是JVM標(biāo)志,指定應(yīng)用程序的堆大小(或者簡(jiǎn)單地說(shuō),應(yīng)用程序?qū)碛卸嗌賰?nèi)存),其中Xms代表堆的初始大小,Xmx代表最大大小。
在我們的例子中,10MB是一個(gè)足夠小的值,可以很快體驗(yàn)到內(nèi)存不足。我們可以看到應(yīng)用程序崩潰,錯(cuò)誤如下:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
在這種情況下,問(wèn)題很明顯。我們只有一個(gè)Java線程和一行代碼。當(dāng)然,實(shí)際應(yīng)用程序要比這復(fù)雜得多。當(dāng)我們?cè)谏a(chǎn)中看到OutOfMemoryError時(shí),查看堆棧跟蹤對(duì)我們沒(méi)有幫助,因?yàn)閷?dǎo)致問(wèn)題的行是相當(dāng)隨機(jī)的,我們正在尋找一個(gè)分配內(nèi)存且不釋放內(nèi)存的代碼。我們可以在JVM內(nèi)部查找問(wèn)題的根源。
讓我們添加一個(gè)-XX:+HeapDumpOnOutOfMemoryError標(biāo)志,它將導(dǎo)致在OutOfMemoryError時(shí)生成堆轉(zhuǎn)儲(chǔ)。
scala Application -J-Xmx10m -J-Xms10m -J-XX:+HeapDumpOnOutOfMemoryError
我們可以看到,當(dāng)我們的應(yīng)用程序崩潰時(shí),生成了一個(gè)擴(kuò)展名為.hprof和PID的文件。這個(gè)文件是二進(jìn)制的,所以我們需要一些工具來(lái)查看里面的內(nèi)容。有很多工具可以完成這項(xiàng)工作,即使是在線的——比如HeapHero(http://heaphero.io/),如果數(shù)據(jù)不敏感,則可以使用。
導(dǎo)入文件后,您可以檢查的最有用的內(nèi)容是所有已分配對(duì)象的列表及其使用的內(nèi)存百分比。我們可以從scala.collection.immutable不可變以及幾乎構(gòu)成整個(gè)堆的整數(shù)。這與我們?cè)陧?xiàng)目中所做的是一致的。列表和整數(shù)是顯而易見(jiàn)的,因?yàn)槲覀儎?chuàng)建List[int]作為結(jié)果。缺點(diǎn). 這是因?yàn)镾cala的LazyList使用了memorization,所以它保留了對(duì)所有元素的引用。
在磁盤空間明顯受限的環(huán)境中(例如在云中),使用-XX:+HeapDumpOnOutOfMemoryError選項(xiàng)時(shí)要小心。這是一個(gè)完整的堆轉(zhuǎn)儲(chǔ),這意味著在OutOfMemoryError的情況下,它至少與最大堆大小一樣大。對(duì)于大的堆,這可能比分配給映像的磁盤空間大得多(因?yàn)槟赡懿恍枰嗫臻g,因?yàn)樽詈貌灰獜姆?wù)直接寫入磁盤)。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743