java程序员遇到的问题_Java 程序员平时最常遇到的故障:系统OOM (一)
作為 Java 程序員而言,先不考慮自己系統外部依賴的緩存、消息隊列、數據庫等等東西掛掉,就我們自己系統本身而言,最常見的掛掉的原因是什么?
其實就是系統OOM,也就是所謂的內存溢出!
什么是內存溢出?在哪些區域會發生內存溢出?
運行一個 Java 系統就是運行一個JVM進程
首先的話呢,大家得先搞明白一個事情,就是我們平時說啟動一個Java系統,其實本質就是啟動一個JVM進程。
咱們就用最最基本的情況來給大家演示一下好了,比如說下面的一段代碼,是每個Java初學者都會寫的一段代碼:
那么大家知道,當你在Eclipse或者Intellij IDEA中寫好這個代碼,然后通過IDE來運行這個代碼的時候,會發生哪些事情嗎?
首先,我們專欄最早的幾篇文章就給大家說過,我們寫好的代碼他都是后綴為“.java”的源代碼,這個代碼是不能運行的。
所以第一步就是這份“.java”源代碼文件必須先編譯成一個“.class”字節碼文件,這個字節碼文件才是可以運行的,如下圖所示。
接著對于這種編譯好的字節碼文件,比如HelloWorld.class,如果里面包含了main方法,接下來我們就可以用“java命令”來在命令行執行這個字節碼文件了
實際上一旦你執行“java命令”,相當于就會啟動一個JVM進程。這個JVM進程就會負責去執行你寫好的那些代碼,如下圖所示。
所以首先要清楚第一點,運行一個Java系統,本質上就是啟動一個JVM進程,這個JVM進程負責來執行你寫好的一大堆代碼。只要你的Java系統中包含一個main方法,接著JVM進程就會從你指定的這個main方法入手,開始執行你寫的代碼。
到底執行哪些代碼:JVM得加載你寫的類
Java是一個面向對象的語言,所以最最基本的代碼組成單元就是一個一個的類,平時我們說寫Java代碼,不就是寫一個一個的類嗎?是不是。
然后在一個一個的類里我們會定義各種變量,方法,數據結構,通過if else之類的語法,寫出來各種各樣的系統業務邏輯,這就是所謂的編程了。
所以JVM既然要執行你寫的代碼,首先當然得把你寫好的類加載到內存里來啊!
所以JVM的內存區域里大家都知道,有一塊區域叫做永久代,當然JDK 1.8以后都叫做Metaspace了,我們也用最新的說法好了。
這塊內存區域就是用來存放你系統里的各種類的信息的,包括JDK自身內置的一些類的信息,都在這塊區域里。
JVM有類加載器和一套類加載的機制,我們在專欄最開始的時候都說過了,這里不再贅述,他會負責把我們寫好的類從編譯好的“.class”字節碼文件里加載到內存里來,如下圖。
好,那么既然有這么一塊Metaspace區域是用來存放類信息的,那是不是有可能在這個Metaspace區域里就會發生OOM?
沒錯,是有這種可能的。
Java虛擬機棧:讓線程執行各種方法
大家都知道,我們寫好的那些Java代碼雖然是一個一個的類,但是其實核心的代碼邏輯一般都是封裝在類里面的各種方法中的
比如JVM已經加載了我們寫好的HelloWorld類到內存里了,接著怎么執行他里面的代碼呢?
Java語言中的一個通用的規則,就是一個JVM進程總是從main方法開始執行的,所以我們既然在HelloWorld中寫了一個main()方法,那么當然得執行這個方法中的代碼了。
但是等一等,JVM進程里的誰去執行main()方法的代碼?
其實我們所有的方法執行,都必須依賴JVM進程中的某個線程去執行,你可以理解為線程才是執行我們寫的代碼的核心主體。
JVM進程啟動之后默認就會有一個main線程,這個main線程就是專門負責執行main()方法的。
大家如下圖所示。
現在又有一個問題了,在main()方法里定義了一個局部變量,“message”,那么大家回憶一下,這些方法里的局部變量可能會有很多,那么這些局部變量是放在哪里的呢?
很簡單,每個線程都有一個自己的虛擬機棧,就是所謂的棧內存。
然后這個線程只要執行一個方法,就會為方法創建一個棧楨,將棧楨放入自己的虛擬機棧里去,然后在這個棧楨里放入方法中定義的各種局部變量,如下圖所示
好,現在問題來了,大家如果還記得之前我們講過的一個參數,應該都知道,我們是可以設置JVM中每個線程的虛擬機棧的內存大小的,一般是設置為1MB。
那么既然每個線程的虛擬機棧的內存大小是固定的,是否可能會發生虛擬機棧的內存溢出?
沒錯,所以第二塊可能發生OOM的區域,就是每個線程的虛擬機棧內存。
堆內存:放我們創建的各種對象
最后我們知道,我們寫好的代碼里,特別在一些方法中,可能會頻繁的創建各種各樣的對象,這些對象都是放在堆內存里的,如下圖所示。
而且我們通過之前的學習,也都知道了一點,通常我們在JVM中分配給堆內存的空間其實一般是固定的
既然如此,我們還不停在堆內存里創建對象,是不是說明,堆內存也有可能會發生內存溢出?
沒錯,第三塊可能發生內存溢出的區域,就是堆內存空間!
總結
以上是生活随笔為你收集整理的java程序员遇到的问题_Java 程序员平时最常遇到的故障:系统OOM (一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java用if语句调用方法_J2SE中m
- 下一篇: C语言图书管理系统注册功能,图书管理系统