1.java内存模型 / java运行时数据区模型?

元空间属于本地内存 而非JVM内存

内存模型

程序计数器

1.作为字节码的行号指示器,字节码解释器通过程序计数器来确定下一步要执行的字节码指令,比如:顺序执行,选择,循环,异常处理等。

2.程序计数器属于线程私有,当线程切换有切回来的时候程序计数器还记着它之前执行到哪一行指令了,可以接着执行。

程序计数器是唯一一个不会出现 OutOfMemoryError 的内存区域,程序计算器所维护的就是下一条待执行的命令的地址,它的生命周期随着线程的创建而创建,随着线程的结束而死亡。

java虚拟机栈

可能出现两种异常:

StackOverFlowError: 若栈的内存大小不允许动态扩展(hotspot),那么当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候,就抛出 StackOverFlowError 错误。

OutOfMemoryError: 如果栈的内存大小可以动态扩展(Classic), 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。

java虚拟机栈是线程私有的,与线程的生命周期同步,主要描述的是方法执行的内存模型。由一个个栈帧组成。

每个方法执行都会创建一个栈帧。也是先进后出的顺序。

每个栈帧包括:局部变量表、操作数栈、动态链接、方法返回地址。

https://blog.51cto.com/u_15334563/3473150

局部变量表:用来存储编译器可知的类型(基本数据类型、对象引用(reference))

 操作数栈:是的方法调用的中转站,用来存放方法和执行过程产生的中间计算结果和计算过程的临时变量。

 动态链接:在一个方法调用另外一个方法时,将符号引用转换为直接引用的过程。(java源文件被编译成字节码时,所有的变量、方法引用都作为符号引用保存在了Class文件的常量池里)

 方法返回地址:用于存放调用该方法的pc寄存器的值,方法结束后出栈过程,恢复上层方法的栈帧信息(恢复上层方法的局部变量表、操作数栈、将返回值入调用者栈帧的操作数栈、设置PC寄存器值等,让调用者方法继续执行下去)

本地方法栈

和java虚拟栈功能类似。java虚拟机栈服务于java方法,本地方法栈服务于本地方法。也由栈帧组成,栈帧包括本地变量表、操作数栈、动态链接、出口信息。在hotspot里。本地方法栈和java虚拟栈合二为一了。

堆是jvm里面最大的一块内存区域,也是垃圾回收器主要工作的场所。几乎所有的对象实例和数组都存放在堆内存里。但是有一些对象实例可以不放在堆里,而放在栈里面。因为这些对象是方法私有的,他们在方法里面被创建,但是没有逃逸出去(未返回,也未被外部引用)。

从 JDK 1.7 开始已经默认开启逃逸分析。

逃逸分析://TODO

堆内存模型:

jdk1.7及以前:堆内存主要由三部分组成:新生代、老年代、永久代组成

jdk1.8:堆内存主要由两部分组成:新生代、老年代。

而之前永久代存放的东西被元空间代替。存放到了直接内存。

“永久代与堆内存存在于连续的物理内存上,可以看作是从堆内存中拿出一部分内存作为永久代,但是两者又是互相隔离的,所以永久代称为非堆,此时永久代的大小受限于堆内存的大小,因为永久代是从堆内存拿的空间,逻辑上是与堆内存连在一起的”

为什么要用元空间取代永久代?

1.减少OOM

因为永久代配置的内存大小是有限的(jvm为永久代设置了一个大小),如果动态生成很多class的时候,很有可能出现java.lang.OutOfMemoryError:PermGen space错误。

2.方便合并 HotSpot 和 JRockit 的代码,Rockit没有永久代的概念。

 堆内存容易发生的OutOfMemoryError 异常

  1. java.lang.OutOfMemoryError: GC Overhead Limit Exceeded : 当 JVM 花太多时间执行垃圾回收并且只能回收很少的堆空间时,就会发生此错误。
  2. java.lang.OutOfMemoryError: Java heap space 新建对象,内存空间不够的时候。

方法区(是逻辑区域)

永久代:

1.7之前 字符串常量池、静态变量、类信息、运行时常量池、JIT代码缓存

1.7 类信息、运行时常量池、JIT代码缓存  (字符串常量池、静态变量被移到了堆了)

1.8没了  被元空间取代了

JDK 1.7 为什么要将字符串常量池移动到堆中

主要是因为永久代(方法区实现)的 GC 回收效率太低,只有在整堆收集 (Full GC)的时候才会被执行 GC。Java 程序中通常会有大量的被创建的字符串等待回收,将字符串常量池放到堆中,能够更高效及时地回收字符串内存。

方法区常用参数有哪些?

JDK 1.8 之前永久代还没被彻底移除的时候通常通过下面这些参数来调节方法区大小。

-XX:PermSize=N //方法区 (永久代) 初始大小
-XX:MaxPermSize=N //方法区 (永久代) 最大大小,超过这个值将会抛出 OutOfMemoryError 异常:java.lang.OutOfMemoryError: PermGen

相对而言,垃圾收集行为在这个区域是比较少出现的,但并非数据进入方法区后就“永久存在”了。

JDK 1.8 的时候,方法区(HotSpot 的永久代)被彻底移除了(JDK1.7 就已经开始了),取而代之是元空间,元空间使用的是直接内存。下面是一些常用参数:

-XX:MetaspaceSize=N //设置 Metaspace 的初始(和最小大小)
-XX:MaxMetaspaceSize=N //设置 Metaspace 的最大大小 默认unlimited

与永久代很大的不同就是,如果不指定大小的话,随着更多类的创建,虚拟机会耗尽所有可用的系统内存。

直接内存

不属于jvm运行时数据区,也不是jvm规范中定义的内存区域。但是会被频繁使用,也可能出现OOM. 不受jvm内存的限制,但是会收到本机总空间内存和处理器寻址空间的限制。

NIO的应用

NIO引入的channel和buffer的方式,可以直接使用本地函数分配堆外内存,然后通过堆中的DirectByteBuffer 对象作为这块内存的引用进行操作,避免了java堆和本地堆来回复制数据,提高了性能。

2.对象的创建过程

类加载检查->分配内存->设置默认初始值->设置对象头->执行init方法

3.对象的内存布局

对象头:第一部分用于存储对象自身的运行时数据(哈希码、GC 分代年龄、锁状态标志等等),另一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

实例数据

对齐填充:Hotspot 虚拟机的自动内存管理系统要求对象起始地址必须是 8 字节的整数倍

4.对象的访问定位

句柄:局部变量表里面reference保存句柄的地址,根据堆里面的句柄(包含对象实例数据地址和对象类型数据地址),找堆里的实例数据和方法区的类信息->修改对象信息,不用修改栈

直接指针:局部变量表里面reference保存对象的地址,直接找到堆里面的对象实例数据,再从堆里面对象类型数据的指针找方法区的类信息->查找速度快

面试-JVM的更多相关文章

  1. java面试——jvm

    背景:用来总结java面试过程中与jvm相关的问题. 垃圾回收以及优化总结 <JVM 垃圾回收器工作原理及使用实例介绍> 介绍常用的垃圾回收算法,垃圾收集器,垃圾收集器相关的调试参数. J ...

  2. 【面试 JVM】【第六篇】JVM调优

    六部分内容: 一.内存模型 1.程序计数器,方法区,堆,栈,本地方法栈的作用,保存那些数据 可以画个大图出来,很清晰 jvm内存模型主要指运行时的数据区,包括5个部分. 栈也叫方法栈,是线程私有的,线 ...

  3. 不止面试—jvm类加载面试题详解

    面试题 带着问题学习是最高效的,本次我们将尝试回答以下问题: 什么是类的加载? 哪些情况会触发类的加载? 讲一下JVM加载一个类的过程 什么时候会为变量分配内存? JVM的类加载机制是什么? 双亲委派 ...

  4. [jvm][面试]JVM 调优总结

    https://blog.csdn.net/wfh6732/article/details/57422967 堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-b ...

  5. 不止面试-JVM垃圾回收面试题详解

    第一部分:面试题 本次分享我们将尝试回答以下问题: GC 是什么? 为什么要有 GC? 简单说一下java的垃圾回收机制. JVM的常见垃圾回收算法有哪些? 为什么要使用分代回收机制? 如何判断一个对 ...

  6. Java面试- JVM 内存模型讲解

    经常有人会有这么一个疑惑,难道 Java 开发就一定要懂得 JVM 的原理吗?我不懂 JVM ,但我照样可以开发.确实,但如果懂得了 JVM ,可以让你在技术的这条路上走的更远一些. JVM 的重要性 ...

  7. java面试-JVM内存结构

    一.JVM内存结构 二.类加载(classLoader)机制 java中的ClassLoader详解 java类加载机制面试题 java类加载机制面试题 虚拟机把描述类的数据从Class文件加载到内存 ...

  8. java面试-JVM常用的基本配置参数有哪些?

    1.-Xms 初始大小内存,默认为物理内存 1/64,等价于 -XX:InitialHeapSize 2.-Xmx 最大分配内存,默认为物理内存的 1/4,等价于 -XX:MaxHeapSize 3. ...

  9. java面试-JVM调优和参数配置,如何查看JVM系统参数默认值

    一.JVM的参数类型: 1.标配参数: java -version java -help 2.X参数: -Xmixed 混合模式(先编译后执行) -Xint  解释执行 -Xcomp 第一次使用就编译 ...

  10. 面试~jvm(JVM内存结构、类加载、双亲委派机制、对象分配,了解垃圾回收)

    一.JVM内存结构 ▷ 谈及内存结构各个部分的数据交互过程:还可以再谈及生命周期.数据共享:是否GC.是否OOM 答:jvm 内存结构包括程序计数器.虚拟机栈.本地方法栈.堆.方法区:它是字节码运行时 ...

随机推荐

  1. HDLbits——Shift18

    // Build a 64-bit arithmetic shift register, // with synchronous load. The shifter can shift both le ...

  2. Dilated Neighborhood Attention Transformer概述

    0.前言 相关资料: arxiv github 论文解读 论文基本信息: 发表时间:arxiv2022(2022.9.29) 1.针对的问题 之前的方法通过局部注意力机制来降低计算复杂度,但这削弱了自 ...

  3. 使用layui时遇到的问题以及解决文章链接

    1.斜线表头效果 2.表格嵌套使用 3.layui数据表格跨行自动合并 4.layui表格数据变更的处理方式 5.layer弹窗动态添加KindEditor编辑器 6.layer弹出层自动调节位置 7 ...

  4. JS实现另存/打印功能

    代码实现 <div id="main"> <-- 需要保存的内容 --></div> <div @click="printdiv ...

  5. 2022-04-20内部群每日三题-清辉PMP

    1.一个项目已经支出350万美元,现在已经完成400万元美元的工作.该项目的计划价值(PV)为800万美元.主题专家(SME)估算还需要600万美元来完成该项目.完成该项目的技术方法不再有效.当前的完 ...

  6. redhat单网卡配置多个IP

    单网卡配置多个IP 进入配置网络的文件目录 复制网络配置文件并修改名字 配置网络 网络1 网络2 激活网络设备 重启网络 重启计算机,查看IP地址 (有问题可以提出来)

  7. 异步Udp监听关闭 出现异常,访问已释放的资源或者其他错误的解决方法

    在开发异步Udp程序的过程中,通常在关闭UDP的时候回遇到诸如socket 访问已释放的资源之类的异常,如下简单操作下: 1 Udp的监听 2 this.serverSocket = new Sock ...

  8. github进不去

    发现github进不去了:百度解决方案:修改hosts表,文件位置在C:\Windows\System32\drivers\etc 记事本打开,尝试在最后添加140.82.112.4 github.c ...

  9. spring的作用

    Spring能有效地组织你的中间层对象,无论你是否选择使用了EJB.如果你仅仅使用了Struts或其他的包含了J2EE特有API的framework,你会发现Spring关注了遗留下的问题.Sprin ...

  10. HDFS 内部工作机制

    HDFS 内部工作机制 HDFS集群分为两大角色:NameNode.DataNode (Secondary Namenode) NameNode 负责管理整个文件系统的元数据 DataNode 负责管 ...