我們在處理線上問題的時候,如果遇到了程序進程突然被kill掉,可以通過下面的命令來查看程序死掉的時間:
#查看oom被kill的進程
grep "Out of memory" /var/log/messages
或者:
#查看系統日誌:
egrep -i -r 'killed process' /var/log
或者:
dmesg -T| grep java
從這些日誌中我們可以看到程序oom的時間,結合我們程序本身的日誌,可以推算是否是自己的程序掛掉了。
一般java程序在部署的時候會在啓動的腳本中加入dump信息來幫助我們迅速定位線上的問題。
例如我寫個簡單的程序:
public class Main {
public static void main(String[] args) {
List<byte[]> list = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
list.add(new byte[1024000]);
}
}
}
只要程序一運行我們很快就會發現OOM異常:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.xqnode.Main.main(Main.java:10)
從這個異常中我們會快速定位到具體的哪一行出了問題。但是在實際生產環境不會出現這麼簡單的代碼,通常程序是在不同的包中相互調用,而且會有多線程的情況,比較難定位到具體的錯誤發生的代碼,所以我們在啓動腳本中加入dump信息,然後我們就能找到對應的問題所在了。這裏我們制定dump文件輸出到D盤下。
啓動配置:
再次運行程序,出現OOM的時候會在D盤下看到這個文件:
然後我們使用jdk中自帶的工具jvisualvm.exe打開dump文件,路徑在jdk/bin下。
點擊 文件 => 裝入,選擇後綴名,打開文件
看到的界面如下:
我們從上面的紅色部分可以清晰的看到我們的程序錯誤在哪裏。