這張圖我相信基本上對JVM有點接觸的都應該很熟悉,可以說這是JVM入門的第一課。其中的“堆疊”和“虛擬機器堆疊(堆疊)」更是耳熟能詳。下面將圍繞這張圖對JVM的運行時資料區做一個簡單介紹。
程式計數器(Program Counter Register)
## 這和電腦操作系統中的程式計數器類似,在電腦作業系統中程式計數器表示這個行程要執行的下個指令的位址,對於JVM中的程式計數器可以看做是目前執行緒所執行的字節碼的行號指示器,每個線程都有一個程式計數器(這很好理解,每個線程都有在執行任務,如果線程切換後要保證能恢復到正確的位置),重要的一點——程式計數器,這是JVM規格中唯一一個沒有規定會導致OutOfMemory# (記憶體洩露,下文簡稱OOM)的區域。換句話說上圖中的其餘4個區域,都有可能導致OOM。
☆虛擬機堆疊(Java Virtual Machine Stacks)
這塊記憶體區域就是我們常常說的“堆疊”,我們所熟知的是它用來存放變量,也就是說例如:
#int i = 0;虛擬機器棧記憶體就會用
4個位元組來儲存##i變數。對於變數的記憶體空間是一開始就能確定的(對於引用型變量,它當然儲存的就是一個位址引用,其大小也是固定),所以這塊記憶體區域在編譯器就能夠確定下來,這塊區域可能會拋出StackOverflowError或OOM錯誤。設定JVM參數」-Xss228k」(堆疊大小為228k)。
1 package com.jvm; 2 3 /** 4 * -Xss228k,虚拟机栈大小为228k 5 * Created by yulinfeng on 7/11/17. 6 */ 7 public class Test { 8 private static int count = 0; 9 10 public static void main(String[] args) {11 Test test = new Test();12 test.test();13 }14 15 /**16 * 递归调用17 */18 private void test() {19 try {20 count++;21 test();22 } catch (Throwable e) { //Exception已经捕获不了JVM抛出的StackOverflowError23 System.out.println("递归调用次数" + count);24 e.printStackTrace();25 }26 }27 }
這是一段沒有終止條件的遞歸,執行結果如下圖所示,JVM拋出StackOverflowError#表示執行緒請求的堆疊深度大於JVM所允許的深度。
對於單一執行緒情況下,無論如何拋出的都是StackOverflowError。如果要拋出OOM異常,導致的原因是不斷地在建立線程,直到記憶體消耗殆盡。
JVM的記憶體由堆內存 #+ 方法區內存 + 剩餘內存,也就是剩餘記憶體=作業系統分配給JVM#的記憶體 - 堆記憶體 - 方法區記憶體。 -Xss設定的是每個執行緒的堆疊容量,也就是說可以建立的執行緒數量 = 剩餘記憶體 / 堆疊記憶體。此時如果棧記憶體越大,可以建立的執行緒數量就少,就容易出現OOM#;如果堆疊記憶體越小,可以建立的執行緒數量就多,就不容易出現OOM。
要避免這種情況最好就是減少堆疊記憶體+方法區內存,或是適當地減少堆疊記憶體。對於堆疊記憶體的配置,一般採用預設值1M#,或採用64位元作業系統以及64 位元的JVM。
本機方法堆疊(Native Method Stack)
本機方法堆疊和虛擬機器堆疊類似,不同的是虛擬機器堆疊服務的是Java方法,而本機方法堆疊服務的是Native方法。在HotSpot虛擬機器實作中是把本機方法堆疊和虛擬機器堆疊合而為一的,同理它也會拋出StackOverflowError 和OOM異常。
☆Java堆(Java Heap)
########################################对于堆,Java程序员都知道对象实例以及数组内存都要在堆上分配。堆不再被线程所独有而是共享的一块区域,它的确是用来存放对象实例,也是垃圾回收GC的主要区域。实际上它还能细分为:新生代(Young Generation)、老年代(Old Generation)。对于新生代又分为Eden空间、From Survivor空间、To Survivor空间。至于为什么这么分,这涉及JVM的垃圾回收机制,在这里不做叙述。堆同样会抛出OOM异常,下面例子设置JVM参数” -Xms20M -Xmx20M“(前者表示初始堆大小20M,后者表示最大堆大小20M)。
1 package com.jvm; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * -Xms20M -Xmx20M 堆初始大小20M 堆最大大小20M 8 * Created by yulinfeng on 7/11/17. 9 */10 public class Test {11 12 public static void main(String[] args) {13 List<test> list = new ArrayList<test>();14 int count = 0;15 try {16 while (true) {17 count++;18 list.add(new Test()); //不断创建线程19 }20 } catch (Throwable e) {21 System.out.println("创建实例个数:" + count);22 e.printStackTrace();23 }24 25 }26 }</test></test>
执行的结果可以清楚地看到堆上的内存空间溢出了。
☆方法区(Method Area)
对于JVM的方法区,可能听得最多的是另外一个说法——永久代(Permanent Generation),呼应堆的新生代和老年代。方法区和堆的划分是JVM规范的定义,而不同虚拟机有不同实现,对于Hotspot虚拟机来说,将方法区纳入GC管理范围,这样就不必单独管理方法区的内存,所以就有了”永久代“这么一说。方法区和操作系统进程的正文段(Text Segment)的作用非常类似,它存储的是已被虚拟机加载的类信息、常量(从JDK7开始已经移至堆内存中)、静态变量等数据。现设置JVM参数为”-XX:MaxPermSize=20M”(方法区最大内存为20M)。
1 package com.jvm; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * -XX:MaxPermSize=20M 方法区最大大小20M 8 * Created by yulinfeng on 7/11/17. 9 */10 public class Test {11 12 public static void main(String[] args) {13 List<string> list = new ArrayList<string>();14 int i = 0;15 while (true) {16 list.add(String.valueOf(i++).intern()); //不断创建线程17 }18 }19 }</string></string>
其實對於上述程式碼,在JDK6、JDK7、JDK8運行結果均不一樣。原因就在於字串常數池在JDK6的時候還是存放在方法區(永久代)所以它會拋出OutOfMemoryError:Permanent Space#;而JDK7後則將字串常數池移到了Java堆中,上面的程式碼不會拋出OOM,將堆記憶體改為20M則會拋出OutOfMemoryError:Java heap space #;至於JDK8則是純粹取消了方法區這個概念,取而代之的是」#元空間(Metaspace)「,所以在JDK8中虛擬機器參數”-XX:MaxPermSize”也就沒有了任何意義,取代它的是”-XX:MetaspaceSize“#和” -XX:MaxMetaspaceSize”等。
以上是JVM基礎入門之運行時資料區的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Laravel入门教程:从零开始学习最流行的PHP框架引言:Laravel是当前最流行的PHP框架之一,它易于上手、功能强大且拥有活跃的开发社区。本文将带您从零开始学习Laravel框架,并提供一些实例代码,帮助您更好地理解和掌握这个强大的工具。第一步:安装Laravel在开始之前,您需要在计算机上安装Laravel框架。最简单的方法是通过Composer进

Vue.js是一款流行的JavaScript前端框架,目前已经推出了最新的版本——Vue3,新版Vue在性能、体积以及开发体验上均有所提升,受到越来越多的开发者欢迎。本文将介绍如何使用Vue3制作一个简单的图片裁剪器。首先,我们需要创建一个Vue项目并安装所需的插件。可以使用VueCLI来创建项目,也可以手动搭建。这里我们以使用VueCLI的方式为例:#

Go-zero是一款优秀的Go语言框架,它提供了一整套解决方案,包括RPC、缓存、定时任务等功能。事实上,使用go-zero建立一个高性能的服务非常简单,甚至可以在数小时内从入门到精通。本文旨在介绍使用go-zero框架构建高性能服务的过程,并帮助读者快速掌握该框架的核心概念。一、安装和配置在开始使用go-zero之前,我们需要安装它并配置一些必要的环境。1

如何解决C++运行时错误:'outofmemory'?在C++编程中,面对运行时错误是很常见的一件事。其中之一就是“outofmemory”错误,也就是内存不足的错误。这个错误通常发生在程序需要分配更多内存空间,但系统没有足够的内存来满足需求的时候。那么,我们应该如何解决这个问题呢?本文将会提供一些解决方案来处理这种情况。首先,最简单的方式就是调整代

快速入门:使用Go语言函数实现简单的数据可视化功能随着数据的快速增长和复杂性的提高,数据可视化成为了数据分析和数据表达的重要手段。在数据可视化中,我们需要使用合适的工具和技术来将数据转化为易读且易理解的图表或图形。Go语言作为一种高效且易于使用的编程语言,在数据科学领域也有着广泛的应用。本文将介绍如何使用Go语言函数来实现简单的数据可视化功能。我们将使用Go

随着科技的不断发展,人脸识别技术也越来越得到了广泛的应用。而在Web开发领域中,PHP是一种被广泛采用的技术,因此PHP中的人脸识别技术也备受关注。本文将介绍PHP中的人脸识别入门指南,帮助初学者快速掌握这一领域。一、什么是人脸识别技术人脸识别技术是一种基于计算机视觉技术的生物特征识别技术,其主要应用领域包括安防、金融、电商等。人脸识别技术的核心就是对人脸进

Beego是一个基于Go语言的开发框架,它提供了一套完整的Web开发工具链,包括路由、模板引擎、ORM等。如果你想快速入门Beego开发框架,以下是一些简单易懂的步骤和建议。第一步:安装Beego和Bee工具安装Beego和Bee工具是开始学习Beego的第一步。你可以在Beego官网上找到详细的安装步骤,也可以使用以下命令来安装:gogetgithub

Laravel是一个流行的PHP框架,它提供了许多工具和功能,以使开发Web应用程序变得更加轻松和快速。Laravel8已经发布,它带来了许多新的功能和改进。在本文中,我们将学习如何快速入门Laravel8。安装Laravel8要安装Laravel8,您需要满足以下要求:PHP>=7.3MySQL>=5.6或MariaDB>=10.


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

Dreamweaver Mac版
視覺化網頁開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。