JClassLib

理解 JVM Stack 栈帧 Frame

≡放荡痞女 提交于 2020-04-09 03:58:31
前置知识 JVM运行时数据区 栈帧的组成 虚拟机栈 与 栈帧 虚拟机栈( JVM Stack ),由 栈帧 Frame 组成。 Frame - 每个方法对应一个栈帧, 包括以下部分: Local Variable Table (局部变量表) Operand Stack (操作数栈) 操作数栈( Operand Stack )也常称为操作栈,它是一个后入先出(Last In FirstOut,LIFO)栈。 同局部变量表一样,操作数栈的最大深度也在编译的时候写入到Code属性的max_stacks数据项中。 Dynamic Linking (动态链接) 动态链接是一个将符号引用解析为直接引用的过程。 return address (返回地址) a() -> b(),方法a调用了方法b, b方法的返回值放在什么地方 方法退出时会做的操作: 恢复上一个方法(调用者的栈帧)的 Local Variable Table (局部变量表)和 Operand Stack (操作数栈) 将返回的变量压入 上一个方法(调用者的栈帧)的 Operand Stack (操作数栈) 调整 Program Counter Register (PC, 程序计数器) 的值为 当前帧的返回地址 当前栈帧弹出 JVM Stack 栈, 执行 Program Counter Register (PC, 程序计数器

开发工具推荐

醉酒当歌 提交于 2020-02-26 18:13:11
1.前言 <br/> 俗话说:“工欲善其事,必先利其器”。 为了助力大家的学习和进阶,本小节介绍几个对 Java 学习非常有帮助的 IDEA 插件,代码反编译和反汇编工具,以及非常不错的网站等。 <br/><br/><br/> 2. IDEA 插件 首先不必多说,IDEA 是目前 Java工程师最主流的开发工具, IDEA 的强大之处不仅在于自身,还在于提供了丰富的插件(这点和谷歌浏览器非常类似)。 本部分介绍几款强大实用的 IDEA 插件,助力大家开发。 以下插件大都可以通过 IDEA 自带的插件管理中心安装,如果搜不到可以去 IDEA 插件官网下载本地导入。 <br/> 2.1 Alibaba Java Coding Guidelines 首先要推荐的是阿里巴巴 Java代码规范插件。 安装该插件后,代码超过 80 行、手动创建线程池等,这些和《手册》中的规约不符时,IDEA中会给出警告提示。 建议大家一定一定一定要安装该插件,它会帮助你检查出很多隐患,督促你写更规范的代码。 <br/><br/> 2.2 jclasslib bytecode viewer <br/> 下面要隆重介绍的是一款可视化的字节码查看插件:jclasslib 。 大家可以直接在 IDEA 插件管理中安装(安装步骤略)。 使用方法: 在 IDEA 打开想研究的类; 编译该类或者直接编译整个项目(

Java中的局部变量表及使用jclasslib进行查看

我与影子孤独终老i 提交于 2019-12-06 10:14:52
什么是局部变量表 在《java中的栈》中我们说到了一个栈帧至少需要包含局部变量表、操作数栈、帧数据区这三个部分。局部变量表是用于保存函数的参数以及局部变量的。顾名思义,局部变量表中的变量只在当前的函数的用中有效,当函数调用结束后,随着函数栈帧的销毁,局部变量表也会随之被销毁。 由于局部变量表在栈帧之中,因此,如果函数的参数和局部变量很多,会使得局部变量表膨胀,因此,每一次函数调用,其局部变量表就会占用更多的栈空间,最终导致函数的嵌套调用的次数减少。 代码来帮忙 public class TestStackDeepth { private static int length=0; public static void recursion(long a,long b,long c) { long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=11; length++; recursion(a, b, c); } public static void main(String[] args) { try { recursion(1l,2l,3l); } catch (Throwable ex) { System.out.println(length); } } } 使用jclasslib 打开jclasslib,选择对应的3中.class文件

Java中的局部变量表及使用jclasslib进行查看

一曲冷凌霜 提交于 2019-12-04 17:36:04
什么是局部变量表 在《java中的栈》中我们说到了一个栈帧至少需要包含局部变量表、操作数栈、帧数据区这三个部分。局部变量表是用于保存函数的参数以及局部变量的。顾名思义,局部变量表中的变量只在当前的函数的用中有效,当函数调用结束后,随着函数栈帧的销毁,局部变量表也会随之被销毁。 由于局部变量表在栈帧之中,因此,如果函数的参数和局部变量很多,会使得局部变量表膨胀,因此,每一次函数调用,其局部变量表就会占用更多的栈空间,最终导致函数的嵌套调用的次数减少。 代码来帮忙 public class TestStackDeepth { private static int length=0; public static void recursion(long a,long b,long c) { long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=11; length++; recursion(a, b, c); } public static void main(String[] args) { try { recursion(1l,2l,3l); } catch (Throwable ex) { System.out.println(length); } } } 使用jclasslib 打开jclasslib,选择对应的3中.class文件

String ,  StringBuffer ,  StringBuilder的区别

做~自己de王妃 提交于 2019-11-27 04:00:31
String , StringBuffer , StringBuilder的区别 String 首先,String 是用来表示一个字符串常量的,它是一个不可变对象,意味着,一旦我们创建了某个字符串之后,就不能再改变它的值了,我们可以从它的源码中看到,它是使用一个 final 的数组来存放内容的,即表示它是一个常量。 /** The value is used for character storage. */ private final char value[]; 接下来看个例子: public class Main { public static void main(String[] args) { String s1 = "a"; String s2 = "a"; String s3 = new String("a"); System.out.println(s1 == s2); // true System.out.println(s1 == s3); // false String s4 = new String("b"); String s5 = new String("b"); System.out.println(s4 == s5); // false String s6 = "a" + "b"; String s7 = "ab"; System.out