「簡單」的內存泄露和溢出

前言

小時候記得印象最喜歡的應該就是小智的卡比獸了。然而不管是金,銀仍是其餘版本中,卡比獸都好弱啊~~~不過,卡比獸的「內存」是真的大呢,好像永遠都不會溢出或者泄漏呢,等等,這什麼意思!!html

內存溢出

解釋

所謂的內存溢出,從字面上的意思即jvm內存不夠用了,目前沒法存放建立的對象。java

緣由

  1. JVM分配的內存相對較小,也許是機器的內存原本就小,也能夠是jvm參數xmx設置的較小。
  2. 某段代碼進行了死循環,致使對象瘋狂產生,可是又不會觸發GC,因此就內存溢出了。
public void 建立GC的方法(){
    List list = new ArrayList<>();
    while(true){
        Person p1 = new Person(); # p1變量老是指向不一樣的對象,應該會Gc
        p1.setAge("23");
        list.add(p1); # 可是list原理是數組,又指向了建立的對象,致使沒法GC
    }
}
其實這也能算是一種內存泄漏了。
複製代碼
  1. 建立的對象太大,最典型的就是IO了。對象太大致使新生代存放不下,只能存放到老年代。而老年代也存放不下,只能OOM了。

解決(對應上述的解釋)

  1. 增大服務器內存,設置xmxxms
  2. 這時候是必定會GC的,經過線程dump和堆dump。分析出現問題的代碼
  3. 增大jvm內存,及時關閉流,及時GC。

內存泄露

解釋

再也不會被使用的對象不能被回收,就是內存泄露。說的通俗點就是:該對象已經須要被GC了,卻沒有這麼作。數組

緣由

看一段代碼:bash

public class Simple {
    Object o1;
    public void method1(){
        o1 = new Object();
        //...其餘代碼
    }
在Simple的實例沒有被回收以前,object對象就不會被回收。緣由就是由於o1是實例變量
複製代碼

解決

public class Simple {
    Object o1;
    public void method1(){
        o1 = new Object();
        //...其餘代碼
        o1 = null
    }
無論是採用引用計數,或者是GC Root判斷是否應該GC,當o1 指向 null後,o1這個對象都會被GC
複製代碼
public class Simple {
    public void method1(){
        Object o1 = new Object();
        //...其餘代碼
        o1 = null
    }
o1 的生命週期就只是這個方法了,因此o1這個對象將會被GC。
因此須要記住,設置實例變量時或者類變量 初始化時,想一下GC問題
複製代碼

什麼是OOM

引用一段話:
OOM,全稱Out Of Memory,翻譯成中文就是「內存用完了」,來源於java.lang.OutOfMemoryError
看下關於的官方說明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.
意思就是說,當JVM由於沒有足夠的內存來爲對象分配空間而且垃圾回收器也已經沒有空間可回收時,就會拋出這個error(注:非exception,由於這個問題已經嚴重到不足以被應用處理)。服務器

結語

內存溢出是必定會產生OOM的。而內存泄漏到達必定程度會致使內存溢出,產生OOM,如上述的list.add()。 參考自:連接markdown

真羨慕卡比獸的肚子啊~~~jvm

相關文章
相關標籤/搜索