日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

java程序员遇到的问题_Java 程序员平时最常遇到的故障:系统OOM (一)

發布時間:2023/11/27 windows 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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程序员遇到的问题_Java 程序员平时最常遇到的故障