java虚拟机 jvm 栈数据区

简介: java栈帧还是需要一些数据支持常量池的解析、正常方法的返回和异常的处理。大部分的java字节码指令需要进行常量池的访问,在栈帧数据区中保存着访问常量池的指针,方便程序访问java常量池。

java栈帧还是需要一些数据支持常量池的解析、正常方法的返回和异常的处理。大部分的java字节码指令需要进行常量池的访问,在栈帧数据区中保存着访问常量池的指针,方便程序访问java常量池。如下图所示:

 


当函数返回或者程序出现异常的时候,jvm虚拟机必须恢复调用者函数的栈帧,并且让调用者函数继续执行。什么意思呢?举一个通俗的例子:

a()调用b()b()返回的时候肯定继续让a()继续执行对吧。b()抛出异常的时候a()肯定也需要处理对吧。

对于异常的处理,jvm是如何处理的呢?虚拟机肯定必须有一个异常处理表,方便发生异常的时候找到处理异常的代码,方便程序继续运转,因此异常处理表Exception table也是帧数据区中很重要的一部分。怎么获取Exception table 中的信息呢操作如下:

执行命令

javap -verbose命令输出它的字节码(不懂这个命令的可以javap -help查看)

from   to  target type  

     0     8     19   any

表示在字节码 0-8个字节可能抛出异常,如果遇到异常,则跳转到字节码偏移量19出执行,当方法抛出异常的时候,虚拟机就会查找类似的异常表进行处理,如果无法找到异常表中对应的信息,则会结束当前程序的调用,返回调用函数,并在调用函数中抛出这个异常信息,并查找函数的异常表进行处理。

通俗易懂的说:

a()调用b()  b()方法中有异常的时候,b()中处理了则继续执行,程序没有处理也就没有异常表信息直接抛异常到a()方法,b()栈移除,a()处理了继续流转,没有处理直接异常抛出。

1.1.1. 栈上分配

栈上分配是java虚拟机提供的一种优化技术,基本思想是,对于那些线程私有对象(不可能被其他线程访问的对象),可以将他们打散分配到栈上,而不是分配在堆上,(是不是很毁三观啊,是不是以前认识的都不对啊白着急)。分配在栈上面的好处函数调用完成后直接自杀销毁,而不需要垃圾回收机制介入回收,所以这样对于性能的提升还是蛮有帮助的。

 

栈上分配有一个前提条件:开启逃逸分析(必须否则不会栈上分配),逃逸分析的目的就是判断对象的作用域是否有可能逃逸出函数体。如下代码:

private static Useruser;

public static void alloc(){

user=new User();

user.setId(5);

user.setName("springok");

}

对象User user 因为是static  方法中因此可以被任何线程访问到。所以属于逃逸对象。

下面的代码显示了一个非逃逸对象:

public static void alloc(){

 User user;

user=new User();

user.setId(5);

user.setName("springok");

}

因为不可以被其他的线程访问到。对象user以局部变量形式存在,该对象没有被返回出去,也没有任何地方可以访问到在其他的方法中,因此是非逃逸的,所以虚拟机可能将user分配在栈上。下面的代码对其结论进行证明:

 

public static void alloc() {

User user = new User();

user.setId(5);

user.setName("springok");

}

 

public static void main(String[]args) {

long begin = System.currentTimeMillis();

 

for (int i = 0;i < 100000000;i++) {

alloc();

}

long end = System.currentTimeMillis();

System.out.println(end-begin);

}

上面代码进行一亿次调用进行对象的创建,累计分配的内存可能达到了1.5G,如果堆空间小于这个1.5G肯定会GC垃圾回收,所以我们开启垃圾回收的参数。

运行配置的参数如下:

-server -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-UseTLAB -XX:+EliminateAllocations

jvm参数使用说明:

-server  因为在server模式才能启用逃逸分析。

-XX:+DoEscapeAnalysis 启用逃逸分析

-Xmx10m 堆空间最大10MB.如果对象在堆上创建肯定会GC垃圾回收的。

-XX:+PrintGC 打印GC日志。

-XX:+EliminateAllocations 开启标量替换默认就是开启的,允许对象打散分配到栈上。

user对象拥有的idname属性将会被视为独立的局部变量分配。

-XX:-UseTLAB 关闭TLAB

程序执行后完整的打印如下:

5

可以看到没有任何形式的GC输出,程序执行完毕了。说明user对象确实在分配过程被优化了。

如果关闭逃逸分析或者标量替换任意一个,再次执行程序,就会看到大量的GC日志如下:

[GC 3226K->474K(9920K), 0.0001595 secs]

[GC 3226K->474K(9920K), 0.0001488 secs]

[GC 3226K->474K(9920K), 0.0001726 secs]

[GC 3226K->474K(9920K), 0.0001614 secs]

1556

代码侧面印证了结论的正确性。

第一说明了上面的结论,栈上分配依赖逃逸分析和标量替换的实现,第二确实开启了对象被分配在栈上,而不是堆上。因为在堆上肯定会GC垃圾回收的。

对于大量零散的小对象,栈上分配提供了很好的优化策略,栈上分配速度快,可以避免垃圾回收。但由于和堆相比栈的空间小,因此大对象不适合在栈上分配。

    

相关文章
|
2月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
72 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
2月前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
36 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
|
2月前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
2月前
|
存储 算法 Java
深入理解Java虚拟机(JVM)及其优化策略
【10月更文挑战第10天】深入理解Java虚拟机(JVM)及其优化策略
45 1
|
2月前
|
安全 Java API
🌟探索Java宇宙:深入理解Java技术体系与JVM的奥秘
本文深入探讨了Java技术体系的全貌,从Java语言的概述到其优点,再到Java技术体系的构成,以及JVM的角色。旨在帮助Java开发者全面了解Java生态,提升对Java技术的认知,从而在编程实践中更好地发挥Java的优势。关键词:Java, JVM, 技术体系, 编程语言, 跨平台, 内存管理。
41 2
|
2月前
|
小程序 Oracle Java
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
这篇文章是关于JVM基础知识的介绍,包括JVM的跨平台和跨语言特性、Class文件格式的详细解析,以及如何使用javap和jclasslib工具来分析Class文件。
49 0
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
|
前端开发 Java 应用服务中间件
【Java虚拟机】JVM类加载机制和双亲委派模型
【Java虚拟机】JVM类加载机制和双亲委派模型
【Java虚拟机】JVM类加载机制和双亲委派模型
|
安全 Java 应用服务中间件
深入理解JVM虚拟机6:深入理解JVM类加载机制
深入理解JVM类加载机制 简述:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。
|
22天前
|
存储 SQL 数据库
虚拟化数据恢复—Vmware虚拟机误还原快照的数据恢复案例
虚拟化数据恢复环境: 一台虚拟机从物理机迁移到ESXI虚拟化平台,迁移完成后做了一个快照。虚拟机上运行了一个SQL Server数据库,记录了数年的数据。 ESXI虚拟化平台上有数十台虚拟机,EXSI虚拟化平台连接了一台EVA存储,所有的虚拟机都存放在EVA存储上。 虚拟化故障: 工组人员误操作将数年前迁移完成后做的快照还原了,也就意味着虚拟机状态还原到数年前,近几年数据都被删除了。 还原快照相当于删除数据,意味着部分存储空间会被释放。为了不让这部分释放的空间被重用,需要将连接到这台存储的所有虚拟机都关掉,需要将不能长时间宕机的虚拟机迁移到别的EXSI虚拟化平台上。
96 50
|
2月前
|
安全 虚拟化 数据中心
Xshell 连接 VMware虚拟机操作 截图和使用
Xshell 连接 VMware虚拟机操作 截图和使用
55 4