JVM(二):畫骨
- 2019 年 10 月 3 日
- 筆記
概述
我們首先來認識一下JVM
的運行時數據區域,如果說JVM
是一個人,那麼運行時數據區域就是這個人的骨架,它支撐着JVM的運行,所以我們先來學習一下運行時數據區域的分類和簡單介紹。
分類
從所在區域角度上來說,可以分為內部內存和外部內存,其中內部的內存又包括了線程獨佔區和線程共享區。
在JVM內部,從線程共享角度上來說,又可以分為線程獨佔區和線程共享區。
線程獨享區可以中包含以下三種數據區域:
-
程序計數器(Program Counter Register)
-
虛擬機棧(VM Stack)
-
本地方法棧(Native Method Stack)
線程共享區中包含以下兩種數據區域:
- 方法區(Method Area)
- 堆(Heap)
在JVM外部也就是本地內存中,包含了直接內存和元數據(Metadata),在JDK 1.8中,元數據就是我們之前的永久代(持久代)
他們之間的區別是,JDK 7在持久代中的常量池在JDK 8移到了堆內存中,剩餘部分移到了元數據中。
多線程的實現原理
上面我們把運行時的數據區域分為了線程獨佔區和線程共享區,那麼Java中的多線程是怎麼實現的呢?這可以幫助我們對於線程獨佔區和共享區有更深的理解。
在多個線程運行的時候,其實是把CPU的使用時間分割成了無數個小份,然後根據優先級去給這些線程分配時間,CPU在這些小時間塊中快速切換,給用戶的感受就是多線程同時在運行,如下圖:
通過這個圖,我們可以清晰的看出是如何達到多線程的效果(其實在通信的時候也有同樣的原理——時分多路復用)
其實通俗一點來說,線程的獨佔區主要是為了控制方法的正常運行,而線程的共享區更類似於一個存儲信息的倉庫。
打個簡單的比方,現在有一個方法,我們使用兩個線程同時去調用這個方法,屬於該方法的信息就可以稱之為獨佔區,而類中的變量,對象卻可以被兩個方法同時使用。
兩種異常
在和JVM打交道的過程中,我們經常會遇到兩種錯誤:StackOverflowError
和OutOfMemoryError
,
StackOverflowError
異常出現在線程獨佔區的本地方法棧和虛擬機棧中,而OutOfMemoryError
會出現在除程序計數器外的所有區域。
公眾號
原創文章,才疏學淺,如有不對之處,萬望告知!