jvm内存模型 基于1.8

jvm内存模型

一、简要模型

  • 在jdk1.8之前List item
  • jdk1.8之后
    在这里插入图片描述
  • 两个版本之间的区别
    • 元数据区取代了永久代的方法区。元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元数据空间并不在虚拟机中,而是使用本地内存

二、各区域详细介绍

1. 程序计数器

  • 一块较小的内存空间, 是当前线程所执行的字节码的行号指示器,每条线程都要有一个独立的 程序计数器,这类内存也称为“线程私有”的内存。
  • 正在执行 java 方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。如 果还是Native方法,则为空
  • 这个内存区域是唯一一个在虚拟机中没有规定任何OutOfMemoryError情况的区域。

2. java虚拟机栈

  • 是描述java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame) 用于存储局部变量表、操作数栈、动态链接、方法出口等信息
  • 每一个方法从调用直至执行完成 的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程
  • 栈帧随着方法调用而创建,随着方法结束而销毁——无论方法是正常完成还是异常完成(抛出了在方法内未被捕获的异 常)都算作方法结束。
    在这里插入图片描述

3.本地方法栈

  • 本地方法区和Java Stack作用类似, 区别是虚拟机栈为执行Java方法服务, 而本地方法栈则为 Native方法服务

4.堆

  • 是被线程共享的一块内存区域,创建的对象和数组以及类的静态变量都保存在 Java 堆内存中,也是垃圾收集器进行 垃圾收集的重要的内存区域。由于现代VM采用分代收集算法, 因此Java堆从GC的角度还可以 细分为: 新生代( Eden 区 、 From Survivor 区 和 To Survivor 区 )和老年代
    在这里插入图片描述

5.常量池

  • 1.7把字符串常量池从永久代中剥离出来,存放在堆空间中。原因是存放在永久方法区的常量池会出现性能问题和内存溢出
  • 用于存放编译期生成的各种字面量和符号引用

6.元数据区

  • 元数据区和永久代本质上都是方法区的实现。方法区存放虚拟机加载的类信息,静态变量,常量等数据
  • 大部分类源数据都在本地内存中分配(MaxMetaspaceSize)参数可以限制本地内存分配给元数据区的大小
  • 实时监控和调整空间有利于垃圾回收的频率和减少延时。

三、String.inter()方法

  • 这个方法是一个 native 的方法,但注释写的非常明了。“如果常量池中存在当前字符串, 就会直接返回当前字符串. 如果常量池中没有此字符串, 会将此字符串放入常量池中后, 再返回”。
发布了20 篇原创文章 · 获赞 0 · 访问量 257

猜你喜欢

转载自blog.csdn.net/white_zzZ/article/details/103940725