潮州市网站建设,快速网站模板公司,网站蓝色和红色搭配,做红k线网站什么是运行时数据区#xff1f;
运行时数据区指的是JVM所管理的内存区域#xff0c;其中分成两大类#xff1a; 线程共享 – 方法区、堆 方法区#xff1a;存放每一个加载的类的元信息、运行时常量池、字符串常量池。 堆#xff1a;存放创建出来的对象。
线程不共享 – …什么是运行时数据区
运行时数据区指的是JVM所管理的内存区域其中分成两大类 线程共享 – 方法区、堆 方法区存放每一个加载的类的元信息、运行时常量池、字符串常量池。 堆存放创建出来的对象。
线程不共享 – 本地方法栈、虚拟机栈、程序计数器 本地方法栈和虚拟机栈都存放了线程中执行方法时需要使用的基础数据。 程序计数器存放了当前线程执行的字节码指令在内存中的地址。
直接内存主要是NIO使用由操作系统直接管理不属于JVM内存 程序计数器
程序计数器Program Counter Register也叫PC寄存器每个线程会通过程序计数器记录当前要执行的的字节码 指令的地址。主要有两个作用
1、程序计数器可以控制程序指令的进行实现分支、跳转、异常等逻辑 2、在多线程执行情况下Java虚拟机需要通过程序计数器记录CPU切换前解释执行到那一句指令并继续解释运行。 栈 - Java虚拟机栈
Java虚拟机栈采用栈的数据结构来管理方法调用中的基本数据先进后出 ,每一个方法的调用使用一个栈帧来保存。 每个线程都会包含一个自己的虚拟机栈它的生命周期和线程相同.
栈帧主要包含三部分内容 1、局部变量表在方法执行过程中存放所有的局部变量。 2、操作数栈虚拟机在执行指令过程中用来存放临时数据的一块区域。 3、帧数据主要包含动态链接、方法出口、异常表等内容
动态链接方法中要用到其他类的属性和方法这些内容在字节码文件中是以编号保存的运行过程中需要替换成 内存中的地址这个编号到内存地址的映射关系就保存在动态链接中。 方法出口方法调用完需要弹出栈帧回到上一个方法程序计数器要切换到上一个方法的地址继续执行方法出 口保存的就是这个地址。 异常表存放的是代码中异常的处理信息包含了异常捕获的生效范围以及异常发生后跳转到的字节码指令位置。
本地方法栈
⚫ Java虚拟机栈存储了Java方法调用时的栈帧而本地方法栈存储的是native本地方法的栈帧。 ⚫ 在Hotspot虚拟机中Java虚拟机栈和本地方法栈实现上使用了同一个栈空间。本地方法栈会在栈内 存上生成一个栈帧临时保存方法的参数同时方便出现异常时也把本地方法的栈信息打印出来 堆
⚫ 一般Java程序中堆内存是空间最大的一块内存区域。创建出来的对象都存在于堆上。 ⚫ 栈上的局部变量表中可以存放堆上对象的引用。静态变量也可以存放堆对象的引用通过静态变量就可以实 现对象在线程之间共享。 ⚫ 堆是垃圾回收最主要的部分堆结构更详细的划分与垃圾回收器有关 方法区
方法区是Java虚拟机规范中提出来的一个虚拟机概念在HotSpot不同版本中会用永久代或者元空间来实现。方法 区主要存放的是基础信息包含 1、每一个加载的类的元信息基础信息。 2、运行时常量池保存了字节码文件中的常量池内容避免常量内容重复创建减少内存开销。 3、字符串常量池存储字符串的常量。 直接内存
直接内存并不在《Java虚拟机规范》中存在所以并不属于Java运行时的内存区域。在 JDK 1.4 中引入了 NIO 机 制由操作系统直接管理这部分内容主要为了提升读写数据的性能。在网络编程框架如Netty中被大量使用。 要创建直接内存上的数据可以使用ByteBuffer。 语法 ByteBuffer directBuffer ByteBuffer.allocateDirect(size);
哪些区域会出现内存溢出会有什么现象
内存溢出指的是内存中某一块区域的使用量超过了允许使用的最大值从而使用内存时因空间不足而失败虚拟机一般 会抛出指定的错误。 在Java虚拟机中只有程序计数器不会出现内存溢出的情况因为每个线程的程序计数器只保存一个固定长度的地址。 堆内存溢出 堆内存溢出指的是在堆上分配的对象空间超过了堆的最大大小从而导致的内存溢出。堆的最大大小使用-Xmx参数进 行设置如-Xmx10m代表最大堆内存大小为10m。
溢出之后会抛出OutOfMemoryError并提示是Java heap Space导致的 栈内存溢出 栈内存溢出指的是所有栈帧空间的占用内存超过了最大值最大值使用-Xss进行设置比如-Xss256k代表所有栈帧占用 内存大小加起来不能超过256k。 溢出之后会抛出StackOverflowError 方法区内存溢出 方法区内存溢出指的是方法区中存放的内容比如类的元信息超过了方法区内存的最大值JDK7及之前版本方法区使用永 久代-XX:MaxPermSize值来实现JDK8及之后使用元空间-XX:MaxMetaspaceSize值来实现。元空间溢出 永久代溢出 直接内存溢出 直接内存溢出指的是申请的直接内存空间大小超过了最大值使用 -XX:MaxDirectMemorySize值 设置最大值。 溢出之后会抛出OutOfMemoryError 哪些区域会出现内存溢出会有什么现象 内存溢出指的是内存中某一块区域的使用量超过了允许使用的最大值从而使用内存 时因空间不足而失败虚拟机一般会抛出指定的错误。 堆溢出之后会抛出OutOfMemoryError并提示是Java heap Space导致的。 栈溢出之后会抛出StackOverflowError。 方法区溢出之后会抛出OutOfMemoryErrorJDK7及之前提示永久代JDK8及之 后提示元空间。 直接内存溢出之后会抛出OutOfMemoryError JVM在JDK6-8之间在内存区域上有什么不同 – 方法区的实现
⚫ 方法区是《Java虚拟机规范》中设计的虚拟概念每款Java虚拟机在实现上都各不相同。Hotspot设计如下 ⚫ JDK7及之前的版本将方法区存放在堆区域中的永久代空间堆的大小由虚拟机参数来控制。 ⚫ JDK8及之后的版本将方法区存放在元空间中元空间位于操作系统维护的直接内存中默认情况下只要不超过操作系统承受的上限可以一直分配。也可以手动设置最大大小。 使用元空间替换永久代的原因 1、提高内存上限元空间使用的是操作系统内存而不是JVM内存。如果不设置上限只要不超过操作系统内存上限就可以持续分配。而永久代在堆中可使用的内存上限是有限的。所以使用元空间可以有效减少OOM情况 的出现。 2、优化垃圾回收的策略永久代在堆上垃圾回收机制一般使用老年代的垃圾回收方式不够灵活。使用元空间之后单独设计了一套适合方法区的垃圾回收机制。
JVM在JDK6-8之间在内存区域上有什么不同 – 字符串常量池的位置
早期设计时字符串常量池是属于运行时常量池的一部分他们存储的位置也是一致的。后续做出了调整将字符串常量池和运行时常量池做了拆分 字符串常量池从方法区移动到堆的原因 1、垃圾回收优化字符串常量池的回收逻辑和对象的回收逻辑类似内存不足的情况下如果字符串常量池中的常量不被使用就可以被回收方法区中的类的元信息回收逻辑更复杂一些。移动到堆之后就可以利用对象的垃圾回收器对字符串常量池进行回收。 2、让方法区大小更可控一般在项目中类的元信息不会占用特别大的空间所以会给方法区设置一个比较小的上限。如果字符串常量池在方法区中会让方法区的空间大小变得不可控。 3、intern方法的优化JDK6版本中intern () 方法会把第一次遇到的字符串实例复制到永久代的字符串常量池中。JDK7及之后版本中由于字符串常量池在堆上就可以进行优化字符串保存在堆上把字符串的引用放入字符串常量池减少了复制的操作 JDK6 JDK7 JDK8