java数组内存溢出_Java内存溢出问题总结
使用Java那么久,在此總結一下Java中常見的內存溢出問題以及對應的解決思路
堆溢出
報錯信息
java.lang.OutOfMemoryError: Java heap space
報錯原因
堆中(新生代和老年代)無法繼續分配對象了;
某些對象的引用長期被持有沒有被釋放,垃圾回收器無法回收;
使用了大量的 Finalizer 對象,這些對象并不在 GC 的回收周期內。
解決辦法
將堆內存 dump 下來,使用 MAT 分析一下,解決內存泄漏;
如果沒有內存泄漏,使用 -Xmx 增大堆內存;
如果有自定義的 Finalizable 對象,考慮其存在的必要性。
GC超載溢出
報錯信息
java.lang.OutOfMemoryError:GC overhead limit exceeded
報錯原因
垃圾回收器超過98%的時間用來做垃圾回收,但回收了不到2%的堆內存。
解決辦法
添加 -XX:-UseGCOverheadLimit 這個啟動參數去掉報警,但這只是一種掩耳盜鈴的方式,一般出現 GC overhead limit exceeded 說明離真正的 OOM 也不遠了;
將堆內存 dump 下來,使用 MAT 分析一下,解決內存泄漏;
如果沒有內存泄漏,使用 -Xmx 增大堆內存;
永久代/元空間溢出
報錯信息
java.lang.OutOfMemoryError: PermGen space 或者
java.lang.OutOfMemoryError: Metaspace(Java8及以上)
報錯原因
永久代是 HotSot 虛擬機對 方法區的具體實現,存放了已被虛擬機加載的類信息、常量、靜態變量、JIT編譯后的代碼等。需要注意的是,在Java8后,永久代有了一個新名字:元空間,元空間使用的是本地內存。永久代里存在的信息也有了若干變化:
字符串常量由永久代轉移到堆中;
和永久代相關的JVM參數已移除。
出現永久代或元空間的溢出的原因可能有如下幾種:
有頻繁的常量池操作(eg. String.intern),這種情況只適用于Java7之前應用;
加載了大量的類信息,且沒有及時卸載;
應用部署完后沒有重啟。
解決辦法
永久代/元空間 溢出的原因比較簡單,解決方法有如下幾種:
Java8前的應用:使用 -XX:MaxPermSize 增加永久代的大小();
Java8及以后的應用:如果設置了 -XX:MaxMetaSpaceSize,調整其大小或者移除掉該參數。
嘗試重啟JVM。
方法棧溢出
報錯信息
java.lang.OutOfMemoryError : unable to create new native Thread
報錯原因
虛擬機在拓展??臻g時,無法申請到足夠的內存空間。一般出現在內存空間過小,但是又創建了大量的線程的場景。
解決辦法
通過-Xss降低的每個線程棧大小的容量,注意-Xms,-Xmx的影響;
線程總數也受到系統空閑內存和操作系統的限制,檢查是否該系統下有此限制:
/proc/sys/kernel/pid_max,
/proc/sys/kernel/thread-max,
max_user_process(ulimit -u),
/proc/sys/vm/max_map_count
數組分配溢出
報錯信息
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
這種情況一般是由于不合理的數組分配請求導致的,消除代碼邏輯錯誤或者調整堆大小。
Swap分區溢出
報錯信息
java.lang.OutOfMemoryError: Out of swap space
這種情況一般是操作系統導致的,可能的原因有:
swap 分區大小分配不足;
機器上其他進程消耗了所有的內存。
本地方法溢出
報錯信息
java.lang.OutOfMemoryError: stack_trace_with_native_method
這種情況表明,本地方法在運行時出現了內存分配失敗。和java.lang.OutOfMemoryError : unable to create new native Thread 保存不同,方法棧溢出出現在 JVM 的代碼層面,而本地方法溢出發生在JNI代碼或本地方法處。
總結
以上是生活随笔為你收集整理的java数组内存溢出_Java内存溢出问题总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 南邮杯CTF 文件包含漏洞实战
- 下一篇: Java语言对字节数组截取指定长度