一、简介

大家都知道,在Java编程中,内存都是由JVM虚拟机自动管理和分配的,如果项目中出现内存溢出或者内存泄漏的问题,如果对JVM内存结构还不太了解的话,解决这些问题将会比较棘手,笔者在学习JVM虚拟机内存结构之前也只是对内存结构有一个很浅的认识,本文将总结一下虚拟机的内存结构,希望能够加深对内存结构的理解。

二、JVM内存结构图

由上图可见,JVM内存结构图主要由类加载子系统、运行时数据区、执行引擎、本地方法接口、本地方法库组成。其中运行时数据区的完整图如下:

运行时数据区主要由: 方法区(jdk1.8之后变成Metaspace元数据区)、堆(最大的内存区域)、虚拟机栈、程序计数器、本地方法栈组成。其中堆内存是最大的一块内存区域,同时也是垃圾回收器主要的收集区域。

三、如何通过参数来控制各区域的内存大小

常见的设置内存大小相关控制参数如下:

  • -Xms :设置堆的最小空间大小
  • -Xmx:设置堆的最大空间大小
  • -XX:NewSize:设置新生代最小空间大小
  • -XX:MaxNewSize:设置新生代最大空间大小
  • -XX:PermSize:设置永久代最小空间大小
  • -XX:MaxPermSize:设置永久代最大空间大小
  • -Xss:设置每个线程的堆栈大小
  • 注意点:没有参数可以设置老年代的空间大小,但是可以通过控制堆内存的空间大小和新生代空间大小来间接控制老年代的空间。

四、JVM内存各个区域详解

【a】堆内存:堆内存是JVM内存结构中最大的一块区域,可以分为新生代和老年代,其中新生代又可以分为:Eden Space、From Survivor Space、To Survivor Space。堆内存是被所有线程共用的一块区域,主要存放new()出来的对象实例,几乎所有的对象实例都在堆里面分配内存。堆内存是垃圾收集器集(GC)中收集的区域,也可以成为“GC堆”。

  • 如果堆内存中没有足够内存来完成对象实例的内存分配,并且内存也无法扩展扩大时,会报内存溢出(OutOfMemoryError)异常。

【b】方法区:方法区主要存放类的代码信息、常量信息、静态变量等数据,与堆内存一样同样是线程共享的区域。方法区可以认为是特殊的堆,但是并不等价,方法区有个别名“非堆”用于与堆内存区分开来。垃圾回收器在方法区的主要工作就是收集常量池信息和负责类型的卸载,但是对于类型的卸载收集工作比较困难,一般不会有什么明显的效果。

  • 如果方法区无法足够空间来满足内存分配时,会报内存溢出(OutOfMemoryError)异常。

【c】Java虚拟机栈:JVM栈和线程的关系比较密切,每创建一个线程都会创建一个栈,所以JVM栈是线程私有的区域,各个线程之间不能共享数据。JVM栈主要作用是描述Java方法的执行过程,每个方法被调用执行一次都会创建一个栈帧(Stack Frame)并进行压栈操作,栈帧主要用于存储局部变量表、操作栈、动态链接、方法出口等信息,每一个方法从调用开始到返回结果出去就对应着一个栈帧从入栈到出栈的过程。

JVM栈是一个后入先出的数据结构,线程运行过程中,只有一个栈帧是处于活跃状态的,被称为"当前活动帧栈",当前活动帧栈始终是虚拟机栈的栈顶元素。

  • 当线程请求的栈深度大于虚拟机所允许的最大深度,将会抛出StackOverFlow异常,当JVM栈扩展内存空间无法申请到足够的内存空间时,将会报内存溢出(OutOfMemoryError)异常。

【d】本地方法栈:本地方法栈,作用与JVM栈类似,都是描述Java方法的执行过程,区别就是JVM栈为执行Java方法(字节码)服务,而本地方法栈为执行Native Method(本地方法)服务。

  • 当线程请求的栈深度大于虚拟机所允许的最大深度,将会抛出StackOverFlow异常,当JVM栈扩展内存空间无法申请到足够的内存空间时,将会报内存溢出(OutOfMemoryError)异常。

【e】程序计数器:程序计数器,是一块比较小的内存区域,保存着当前线程执行的虚拟机字节码指令的内存地址。Java中的多线程,是通过线程间的轮流切换并分配处理器执行时间来实现的,在任何时刻,处理器只能处理一个线程中的一条指令。为了确保线程在切换后还能够回到原来的状态,找到之前执行的指令信息,每个线程都会设立一个程序计数器,每个线程的程序计数器都不一样,互不影响,所以程序计算器是各个线程不能共享的区域。

  • 如果线程正在执行的是一个Java方法,程序计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Natvie方法,程序计数器值则为空(Undefined)。同时,程序计数器也是唯一一个在Java规范中没有规定任何OutOfMemory场景的区域。

五、内存分析示例一

下面通过一个示例并通过画图进行Java内存分析:

【a】首先创建Student类,主要name、age两个属性和sayHello()方法;

public class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void sayHello() {System.out.println("hello..." + name + "-->" + age);}
}

【b】测试类

public class TestStorageStructure01 {public static void main(String[] args) {/*** 1. Student经过类加载器的加载,Student类代码信息、静态变量信息等都存放在方法区中;* 2. student对象存放在栈中,是Student对象的引用,持有堆中new Student()对象的内存地址,通过这个地址可以找到堆中new出来的对象;* 3. new Student()出来的对象存放在堆中, 持有方法区中Student类信息的地址引用;*/Student student = new Student("lisi", 20);/*** 1. 调用sayHello()方法时,会创建一个栈帧对象,存放着方法的参数、过程结果等数据;* 2. 通过栈中student对象持有的地址找到在堆中new出来的Student对象;* 3. 通过堆中持有的方法区中Student类的信息,找到sayHello()方法字节码,执行sayHello()方法,输出结果;* 4. 伴随着栈帧的出栈操作;*/student.sayHello();}}

如上图就是以上代码的大概的执行过程。

六、内存分析示例二

public class Test {static String str1 = new String("123");static String str2 = new String("123");static String str3 = "123";static String str4 = "123";public static void main(String[] args) {String str5 = "123";String str6 = "123";/*** str1/str2都是String对象的引用,分别持有指向堆中new String("123")出来的对象的地址,但是两次new String("123")的地址不一样,所以str1 == str2为false*///falseSystem.out.println("str1 == str2   :-->" + (str1 == str2));/*** str3/str4都直接指向方法区中常量池中的"123"这个常量的地址,地址指向都相同,所以str3 == str4为true.*///trueSystem.out.println("str3 == str4   :-->" + (str3 == str4));/*** 原理类似str3/str4*///trueSystem.out.println("str5 == str6   :-->" + (str5 == str6));}}

七、总结

本文通过对Java虚拟机各个区域的作用以及结构分析,让我们对虚拟机的底层结构进一步熟悉了,并通过两个示例和画图进行了内存分析,本文仅仅是笔者学习的一些总结和见解,不对之处,还请大家指点指点,希望对大家的学习有所帮助。

JVM初识之虚拟机内存结构相关推荐

  1. jvm虚拟机内存结构_JVM体系结构101:了解您的虚拟机

    jvm虚拟机内存结构 Java虚拟机(JVM)架构和Java字节码101的初学者速成班 Java应用程序无处不在,它们在我们的手机,平板电脑和计算机上. 在许多编程语言中,这意味着多次编译代码以使其在 ...

  2. JVM(一)JVM虚拟机内存结构 和 JAVA内存模型(JMM)

    本文转自:浅析java内存模型--JMM(Java Memory Model) - 路易小七 - 博客园,尊重作者,转载请注明出处~ JVM虚拟机内存结构 和 JAVA内存模型 是两个不同的概念 JV ...

  3. Carson带你学JVM:图文解析Java虚拟机内存结构

    前言 了解Java中的对象.变量等存放的内存区域十分重要 本文将全面讲解Java虚拟机中的内存模型 & 分区,希望你们会喜欢 Carson带你学JVM系列文章,具体如下: Carson带你学J ...

  4. JVM运行时的内存结构

    我们都知道,JVM的垃圾收集机制能够帮开发者自动管理内存,了解JVM运行时的内存结构是理解垃圾收集机制的前提.本文主要简单介绍JVM运行时的内存结构. [JVM运行时内存中不同的数据区域] 一.PC寄 ...

  5. 玩点深入的:Java 虚拟机内存结构及编码实战

    本文来源:不会coding 了解JVM内存结构的目的 在Java的开发过程中,因为有JVM自动内存管理机制,不再需要像在C.C++开发那样手动释放对象的内存空间,不容易出现内存泄漏和内存溢出的问题. ...

  6. java虚拟机之二虚拟机内存结构

    我们都知道虚拟机的内存划分了多个区域,并不是一张大饼.那么为什么要划分为多块区域呢,直接搞一块区域,所有用到内存的地方都往这块区域里扔不就行了,岂不痛快.是的,如果不进行区域划分,扔的时候确实痛快,可 ...

  7. Java 虚拟机(JVM)运行时内存结构

    1.PC Register(pc寄存器) Java虚拟机线程都有自己的pc寄存器.一条Java虚拟机线程只会同时执行一个方法的代码,这个方法称为该线程的当前方法.如果这个方法不是native的,那么p ...

  8. JVM启动流程和内存结构

    "Great haste makes great waste" JVM启动流程 JVM是Java程序运行的环境,同时是一个操作系统的一个应用程序进程,因此它有自己的生命周期,也有自 ...

  9. 二十、Java虚拟机内存结构

  10. [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义...

    前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine  ,既然是虚拟机, ...

最新文章

  1. 话里话外:论持续跟踪和及时反馈
  2. Android Eclipse JNI 调用 .so文件加载问题
  3. PostgreSQL — 数据库实例只读锁定
  4. systemverilog硬件设计及建模_3D建模和渲染都吃什么硬件?设计师该如何选购电脑...
  5. SQL server Cannot find one or more
  6. JAVA线程间协作:wait.notify.notifyAll
  7. 《职场一点诀 帆风顺,一定快乐?》读后感
  8. 拥抱 Elasticsearch:给 TiDB 插上全文检索的翅膀
  9. c++primer 第2章 练习题答案 (尚未完善 陆续补充中 基本上已经完成)
  10. Power BI Desktop中的分解树
  11. 强大的DataGrid组件[4]_实现CURD[上]——Silverlight学习笔记[12]
  12. centos7查看设置IP地址
  13. Java开发的学生考勤系统多人脸识别签到二维码签到
  14. python 工资管理软件_Python:企业微信指量发工资条工具 -消息发送模块
  15. 蓝桥杯Python题目(二)
  16. 这篇寒门博士论文致谢火了:回首望过去,可怜无数山...
  17. 高效的vim配置及其插件管理
  18. 实现JPanel切换
  19. CDN加速可以为网络用户解决哪些难题?
  20. 撸免费的oracle cloud服务器并使用脚本自动化部署云服务器

热门文章

  1. 阿里云云计算 20 在线实验--块存储的使用
  2. java接口 数据_一步步学习java后台(三)(接口返回数据处理)
  3. DSSM模型的原理简介,预测两个句子的语义相似度
  4. 无法启动excel服务器以导入_无法启动 web 服务器unable to start embedded tomcat
  5. pwm 正弦波_增强型PWM抑制功能对于直列式电机控制的五大优势
  6. SRGAN:Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network
  7. 现代通信原理14.2:M进制数字调制信号波形的向量表示
  8. Python的矩阵分块
  9. 实例详解机器学习如何解决问题
  10. 【Gym-100085 B】Binary Encoding【思维题】