java虚拟机 jvm 栈数据区
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对象拥有的id和name属性将会被视为独立的局部变量分配。
-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垃圾回收的。
对于大量零散的小对象,栈上分配提供了很好的优化策略,栈上分配速度快,可以避免垃圾回收。但由于和堆相比栈的空间小,因此大对象不适合在栈上分配。
java虚拟机 jvm 栈数据区的更多相关文章
- Java虚拟机运行时数据区
运行时数据区程序计数器Java虚拟机栈本地方法栈Java堆(GC堆)方法区运行时常量池 运行时数据区 Java虚拟机在运行Java程序时,会将它所管理的内存划分为若干个内存区域.这些数据区域有各自的用 ...
- 面试常问的 Java 虚拟机运行时数据区
写在前面 本文描述的有关于 JVM 的运行时数据区是基于 HotSpot 虚拟机. 概述 JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以 ...
- Java 虚拟机运行时数据区
写在前面 本文描述的有关于 JVM 的运行时数据区是基于 HotSpot 虚拟机. 概述 JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以 ...
- 《深入理解Java虚拟机》(二)Java虚拟机运行时数据区
Java虚拟机运行时数据区 详解 2.1 概述 本文参考的是周志明的 <深入理解Java虚拟机>第二章 ,为了整理思路,简单记录一下,方便后期查阅. 2.2 运行时数据区域 Java虚拟机 ...
- 【深入理解Java虚拟机】Java虚拟机运行时数据区
Java虚拟机运行时数据区 线程私有 程序计数器 1.当前线程所执行的字节码的行号指示器. 2.唯一不会发生OutOfMemoryError的区域 3.如果执行的是java方法,计数器值为虚拟机字节码 ...
- 【JVM从小白学成大佬】2.Java虚拟机运行时数据区
目录 1.运行时数据区介绍 2.堆(Heap) 是否可能有两个对象共用一段内存的事故? 3.方法区(Method Area) 4.程序计数器(Program Counter Register) 5.虚 ...
- 【JVM学习】2.Java虚拟机运行时数据区
来源: 公众号: 猿人谷 这里我们先说句题外话,相信大家在面试中经常被问到介绍Java内存模型,我在面试别人时也会经常问这个问题.但是,往往都会令我比较尴尬,我还话音未落,面试者就会"背诵& ...
- Java 虚拟机运行时数据区详解
本文摘自深入理解 Java 虚拟机第三版 概述 Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟 ...
- 笔记:Java虚拟机运行时数据区
Java虚拟机在执行Java程序的过程中会把它管的内存划分为以下若干个不同的区域: 1.程序计数器 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器:由于Java虚拟机的 ...
随机推荐
- [WC 2014]紫荆花之恋
Description 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来. 仔细看看的话,这个大树实际上 ...
- poj3728 商务旅行
[Description]小 T 要经常进行商务旅行,他所在的国家有 N 个城镇,标号为 1,2,3,...,N,这 N 个城镇构成一棵树.每个城镇可以买入和卖出货物,同一城镇买入和卖出的价格一样,小 ...
- 计蒜客NOIP模拟赛D2T2 直线的交点
伦伦刚刚在高中学习了解析几何,学会了计算两条直线的交点.这天,老师给她布置了一道作业.在平面上有 nnn 条直线,他们之间有若干交点.给定一对平板(两条平行的直线),问这有多少对直线,他们的交点在这一 ...
- 51 nod 1427 文明 (并查集 + 树的直径)
1427 文明 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 安德鲁在玩一个叫“文明”的游戏.大妈正在帮助他. 这个游 ...
- 【 lca倍增模板】
题目描述 对于 n(<100000)个点 n-1 条掉权值的边,有 m 个询问,每条询问求两个结点之间的路径上边权的最小值 输入 第一行 n,表示结点个数,接下来 n-1 行,每行 a b w ...
- ●SPOJ 8222 NSUBSTR–Substrings(后缀自动机)
题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 后缀自动机的水好深啊!懂不了相关证明,带着结论把这个题做了.看来这滩深水要以后再来了. 本题要用到一个叫 R ...
- 【bzoj4570 scoi2016】妖怪
题目描述 邱老师是妖怪爱好者,他有n只妖怪,每只妖怪有攻击力atk和防御力dnf两种属性.邱老师立志成为妖怪大师,于是他从真新镇出发,踏上未知的旅途,见识不同的风景. 环境对妖怪的战斗力有很大影响,在 ...
- BZOJ4079 [Wf2014]Pachinko
完整题面: 设f(i,j)表示路径经过(i,j)这个点的概率,列出方程消元. 但暴力消元的复杂度是$O((nm)^3)$,注意每一次消元只会影响前后m个方程,所以我们可以对于第i行,只存[i-m,i+ ...
- spring boot新建项目问题总结
1.启动报:Unregistering JMX-exposed beans on shutdown 原因:以来的Tomcat没有启动 解决办法:在pom.xml加入依赖 <dependency& ...
- 博客迁移,新地址:bfsan.github.io
博客的新内容会在新地址发布(暂时),后期可能会考虑做一个整合同步.