JVM--运行时数据区与内存模型,mysql基础知识

2021/12/28 2:14:37

本文主要是介绍JVM--运行时数据区与内存模型,mysql基础知识,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

注意:

JVM运行时数据区是一种规范,真正的实现 方法区在JDK 8中就是Metaspace,在JDK6或7中就是Perm Space

堆是Java虚拟机所管理内存中最大的一块,在虚拟机启动时创建,被所有线程共享。其中 Java对象实例以及数组都在堆上分配。

虚拟机栈

问题:那一个线程执行的状态如何维护?一个线程可以执行多 少个方法?这样的关系怎么维护呢?

虚拟机栈是一个线程执行的区域,保存着一个线程中方法的调用状态。换句话说,一个Java线程的运行状态,由一个虚拟机栈来保存,所以虚拟机栈肯定是线程私有的,独有的,随着线程的创建而创建。

每一个被线程执行的方法,为该栈中的栈帧,即每个方法对应一个栈帧。调用一个方法,就会向栈中压入一个栈帧;一个方法调用完成,就会把该栈帧从栈中弹出。

栈帧:

栈帧:每个栈帧对应一个被调用的方法,可以理解为一个方法的运行空间。

栈帧中包括局部变量 表、操作数栈、动态链接、方法返回地址和即时信息。

局部变量 表:方法中定义的局部变量以及方法的参数存放在这张表中,局部变量表中的变量不可直接使用,如需要使用的话,必须通过相关指令将其加载至操作数栈中作为操作数使用。

操作数 栈:以压栈和出栈的方式存储操作数的。如 1+1 两个1存储在局部变量 表中, 1+1这个操作在操作数栈中完成。

动态链接:每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接(符号引用编程直接引用)。因为类加载机制

仅仅是将本文件的符号引用变成直接引用 ,当遇到多态的调用时,只能通过运行来确定子类对接的引用是哪一个。

方法返回地址:当一个方法开始执行后,只有两种方式可以退出,一种是遇到方法返回的字节码指令;一种是遇

见异常,并且这个异常没有在方法体内得到处理。

本地方法栈

当前线程执行的方法是Native类型的,这些方法就会在本地方法栈中执行

思考:在Java方法执行的时候如何调用native的方法呢?

通过动态链接来进行调用。

在这里插入图片描述

程序计数器

作用:是记录当前线程的执行位置,线程私有。

如果线程正在执行Java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址;

如果正在执行的是Native方法,则这个计数器为空。

除了上面五块内存之外,其实我们的JVM还会使用到其他两块内存

直接内存(Direct Memory)

并不是虚拟机运行时数据区的一部分,也不是JVM规范中定义的内存区域,但是这部分内存也被频 繁地使用,而且也可能导致OutOfMemoryError 异常出现,所以我们放到这里一起讲解。在JDK 1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区 (Buffer)的I/O 方式,它可以使用Native 函数库直接分配堆外内存,然后通过一个存储在Java 堆 里面的DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能, 因为避免了在Java 堆和Native 堆中来回复制数据。

本机直接内存的分配不会受到Java 堆大小的限制,但是,既然是内存,则肯定还是会受到本机总 内存的大小及处理器寻址空间的限制。因此在分配JVM空间的时候应该考虑直接内存所带来的影 响,特别是应用到NIO的场景。

其他内存:

Code Cache:**JVM本身是个本地程序,还需要其他的内存去完成各种基本任务,比如,JIT 编译器在运行时对热点方法进行编译,就会将编译后的方法储存在Code Cache里面;GC等 功能。需要运行在本地线程之中,类似部分都需要占用内存空间。这些是实现JVM JIT等功能 的需要,但规范中并不涉及

其中栈可以指向堆 case: Object obj=new Ob

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

ject()

方法区指向堆 case: private static Object obj=new Object();

堆指向方法区 case: Class类对象指向它的元数据。 new Object().getClass();

Java对象内存模型

一个Java对象在内存中包括3个部分:对象头、实例数据和对齐填充。

在这里插入图片描述

内存模型设计之–大小端存储

小端存储:便于数据之间的类型转换,例如:long类型转换为int类型时,高地址部分的数据可以 直接截掉。

大端存储:便于数据类型的符号判断,因为最低地址位数据即为符号位,可以直接判断数据的正 负号。

内存模型设计之–Class Pointer

引用定位到对象的方式有两种,一种叫句柄池访问,一种叫直接访问

在这里插入图片描述

直接指针访问对象.png

区别:

句柄池:

使用句柄访问对象,会在堆中开辟一块内存作为句柄池,句柄中储存了对象实例数据(属性值结构体) 的内存地址,访问类型数据的内存地址(类信息,方法类型信息),对象实例数据一般也在heap中开 辟,类型数据一般储存在方法区中。

优点:reference存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为) 时只会改变句柄中的实例数据指针,而reference本身不需要改变。

缺点:增加了一次指针定位的时间开销。 直接访问:

直接指针访问方式指reference中直接储存对象在heap中的内存地址,但对应的类型数据访问地址需要 在实例中存储。

优点:节省了一次指针定位的开销。 缺点:在对象被移动时(如进行GC后的内存重新排列),reference本身需要被修改



这篇关于JVM--运行时数据区与内存模型,mysql基础知识的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程