`
matchless1688
  • 浏览: 26298 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

深入JVM学习笔记 JVM指令介绍

阅读更多
JVM指令介绍

栈和局部变量操作

1、常量入栈操作
  --入栈操作三种方式指明常量的值:常量值隐式包含在操作码内部,常量值在字节码流中如同操作数一样紧随在操作码之后,或者从常量池中取出常量
 
  --Java栈中每一个位置的长度都是一个字长(至少32位宽)
 
  --Java源代码中所有的字符串文字最终都作为入口存储与常量池中。如果同一个应用程序的多个类都使用同样的字符串文字,按摩此字符串文字将在使用它的所有类的class文件中出现。但Java虚拟机会把所有具有相同字符顺序的字符串文字处理为同一个String对象,只会创建一个相应的String对象来表示所有的字符串文字。
  备注:要深刻理解源代码中字符串文字与JVM生成的String对象的差别。
 
  --wide指令:跳转指令并不允许直接跳转到被wide指令修改过的操作码。
 
类型转换

1、设计 byte short和char类型的运算操作首先会把这些值转换为int类型,然后对int类型值进行运算,最后得到int类型的结果。

整数运算

  --取余运算 irem 取反运算 ineg

逻辑运算
  -- "<<" ishl 向左移位 
     ">>" ishr 向右移位
     ">>>" iushr 逻辑移位
    
浮点运算

1、在Java虚拟机中,浮点运算基于32位float类型和64位double类型进行。浮点数由符号、尾数、基数和指数四部分组成。

2、float类型的格式如下,符号位表示为s,指数位表示为e,尾数位表示为m:指数占8位,double类型中占11位
   s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
   指数位的解释有三种方式:
   指数位全为1,表示该数为乘法或者减法所产生的特殊值之一——无穷大或者非数字(NaN),NaN是某种特殊操作,诸如0除以0的结果。
   指数位全是0,表示该数是一个非规范化浮点数。
   其他类型的指数位表示该数十一个规范化的浮点数。

3、float类型的特殊值
   指数位全为1而且尾数位全为0,表示无穷大
   指数位全为1,尾数位不全为0,表示该数为"NaN":Java虚拟机总是为NaN产生同样的尾数,除了尾数中最高有效位为1外,其余全为0
  
4、2的幂指数的确定
   指数位既不全为0,也不全为1,该数即为规范化的浮点数。可以通过把指数看成一个整数,然后减去一个偏移量来确定2的幂指数。对于float类型,偏移量是127,double类型是1023
  
   浮点数表示参考文章:http://apps.hi.baidu.com/share/detail/30212277
  
对象和数组

1、只有对象引用和基本类型可以在Java的栈中以局部变量形式存在,Java栈中不能容纳对象。

2、针对数组的操作码
   --newarray操作码用来创建基本类型的数组
   --anewarray/multianewarray操作码用来创建对象引用的数组
  
finally子句
  --jsr指令是使Java虚拟机跳转到微型子例程的操作码。
  --ret指令的功能是执行从子例程中返回的操作。 
  jsr指令会把返回地址压入栈,在执行子例程开始时又会把返回地址弹出栈,然后存入局部变量中。当finally执行结束后(此结束是指finally执行到了最后一条语句正常执行完毕,不包括抛出异常,或执行return、continue、break等情况),ret指令从局部变量里取出返回地址,然后返回。如果finally子句非正常结束,则根本不会执行ret指令,这也是为什么返回地址要从栈中弹出并存到局部变量的原因,否则如果ret指令不执行该地址将存在在栈中而不会被用到。
 
  --Java虚拟机在finally子句执行完毕钱返回一个值的方式:
 
public class Test4 {
	
	public int test(){
		int i = 0;
		try{
			i = 1;
			return i;
		}finally{
			i = 2;
		}
	}
	public static void main(String[] args) {
		Test4 t = new Test4();
		System.out.println(t.test());
	}
}
---------------------
   i = 1


  虽然finally改变了i的值,但是虚拟机仍会返回执行finally子句前的i的值;如果需要finally子句改变返回值,就不得不在finally子句里加一个return语句,用来返回被finally子句更新过的值(如下代码)。
 
 
public class Test4 {
	
	public int test(){
		int i = 0;
		try{
			i = 1;
		}finally{
			i = 2;
			return i;
		}
	}
	public static void main(String[] args) {
		Test4 t = new Test4();
		System.out.println(t.test());
	}
}
---------------------
  i = 2

 
方法的调用和返回

1、对于实例方法,使用invokevirtual指令;对于类方法,使用invokestatic指令。
 
 
2、方法调用的过程描述
 
 
3、通常使用invokevirtual指令调用实例方法,但在某些特定的情况下,也会使用另外两种操作码——invokespecial和invokeinterface。
  --当根据引用的类型来调用实例方法,而不是根据对象的类来调用的时候,通常使用invokespecial指令。分三种情况:
  1)实例初始化(<init>())方法
  2)私有方法
  3)使用super关键字所调用的方法
  --当给出一个接口的引用时,使用invokeinterface来调用一个实例方法
 
  备注:invokevirtual只能调用当前类的方法,无法使用超类的方法。——对象初始化时在调用自身的<init>()的时候会首先调用父类的<init>()方法,而invokespecial可以完成这样的操作。
 
  释疑: 什么是根据引用的类型,什么是根据对象的类(参考下面的代码可知)
  情况一:
 
public class SuperClass{
  	private void speakHi(){
  	    System.out.println("super class say hi");
  	}
  	
  	void sayHi(){
  	   speakHi();
  	}
  }
  
  public class SubClass extends SuperClass{
  	void speakHi(){
  	    System.out.println("sub class say hi");
  	}
  	
  	public static void main(String[] args){
  		SubClass ins = new SubClas();
  		ins.sayHi();
  	}
  }

  运行结果: super class say hi
  解释:main方法中创建的对象类型是SubClass,但SubClass的sayHi()方法是从SuperClass继承过来的,所以此时引用的类型其实是SuperClass,而invokespecial根据引用的类型来调用实例方法,即SuperClass的speakHi()。且此时所调用方法为私有方法。
 
  情况二:
 public class SuperClass{
  	private void speakHi(){
  	    System.out.println("super class say hi");
  	}
  	
  	void sayHi(){
  	   speakHi();
  	}
  }
  
  public class SubClass extends SuperClass{
  	void speakHi(){
  	    System.out.println("sub class say hi");
  	}
  	
  	void sayHi(){
  	   speakHi();
  	}
  	
  	public static void main(String[] args){
  		SubClass ins = new SubClas();
  		ins.sayHi();
  	}
  }

  运行结果: sub class say hi
  解释:SubClass覆盖了SuperClass的sayHi()方法,此时不仅创建的对象类型是SubClass,真正引用的类型也是,所以调用的就是SubClass的speakHi()。这也从另一面证明了第一种情况的正确性。
 
  --Java虚拟机使用不同于类引用(invokevirtual)的操作码来调用接口引用(invokeinterface)的方法,这是因为Java不能像使用类引用那样,使用许多和方法表偏移量相关的假设。对于类引用来说,无论对象实际的类是什么,方法在方法表中始终占据相同的位置,但对于接口引用来说,情况就不是这样了,位于不同类中的同一方法所占据的位置是不同的,尽管这些类实现同一个接口。

线程同步

1、Java使用的同步机制是监视器。
  --一个线程只有在它正持有监视器时才能执行等待命令,而且它只能通过再次成为监视器的持有者才能离开等待区。
 
2、对象锁
  --堆和方法区是被所有线程共享的,Java程序需要为两种多线程访问数据进行协调:
    保存在堆中的实例变量
    保存在方法区中的类变量
   
3、可重入锁:一个线程可以允许多次对同一个对象上锁。对于每一个对象来说,Java虚拟机维护一个计数器,记录对象被加了多少次锁。没有被锁的对象的计数器是0,当一个线程第一次获得锁的时候计数跳到1,线程没加锁一次,计数器就加1,(只有已经拥有了这个对象的锁的线程才能对该对象再次加锁。在它释放锁之前,其他的线程不能对这个对象加锁)每当线程释放锁一次,计数器就减1,当计数器跳到0的时候,锁就完全被释放了,其他的线程才可以使用它。
  • 大小: 44.5 KB
  • 大小: 286.3 KB
分享到:
评论

相关推荐

    JVM学习笔记(一)

    ### JVM学习笔记(一) #### 一、JVM概述与工具使用 JVM(Java Virtual Machine)是Java语言的核心组成部分之一,它为Java程序提供了一个跨平台的运行环境。本篇学习笔记主要介绍如何利用一系列工具来查看和监控JVM...

    JVM学习笔记

    ### JVM学习笔记 #### JVM内存模型 (JMM) JVM内存模型主要分为以下几个部分: - **Java堆**:这是所有线程共享的一块区域,在虚拟机启动时创建。主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 - *...

    深入JVM笔记word版

    ### 深入解析 JVM 内存区域 #### 一、Java内存区域概述 Java虚拟机(JVM)作为Java程序的运行环境,负责管理和分配内存...理解这些区域对于深入学习JVM原理至关重要,也有助于开发者编写更加高效和可靠的Java应用程序。

    jvm中篇笔记.md

    ### JVM中篇笔记知识点 #### 一、Class 文件结构 ##### 1. 概述 - **字节码文件的跨平台性** - Java 的跨平台性体现在 "Write Once, Run Anywhere" (WORA),即一次编写,到处运行。Java 语言编写的源代码在编译...

    JVM学习笔记核心知识点整理

    ### JVM学习笔记核心知识点整理 #### 一、引言与背景 随着软件开发技术的不断发展,Java作为一种广泛应用的编程语言,其背后的核心技术——Java虚拟机(JVM)的重要性日益凸显。掌握JVM不仅可以帮助开发者更好地理解...

    jvm指令手册 +JVM必知必会,掌握虚拟机编译过程.rar

    《JVM必知必会》记录了对JVM的总结及学习笔记,详解的介绍了什么是jvm,以及弄清楚jvm的工作原理等等,会深入了解JVM有一定的帮助。 Java Virtual Machine(Java虚拟机),它bai是一个虚构出来du的计算机,是通过在...

    jvm学习笔记

    《JVM学习笔记》 Java虚拟机(JVM)是Java平台的核心组成部分,它负责运行所有的Java应用程序。这篇笔记将深入探讨JVM的工作原理、内存管理、类加载机制以及优化策略,帮助读者全面理解JVM并提升Java程序的性能。 ...

    狂神说JVM探究.rar

    这份资料出自B站上的【狂神说Java】系列教程,为快速入门JVM提供了详实的笔记。以下是根据这些资源可能包含的一些关键知识点的详细解析: 1. **JVM概述**: - JVM是Java平台的核心组成部分,它是一个运行Java字节...

    JVM的学习笔记PDF版

    这份“JVM的学习笔记PDF版”应该包含了关于JVM的详细信息,帮助学习者深入理解这个复杂的系统。JVM允许Java代码跨平台运行,通过解释器、类加载器、垃圾收集器等组件实现“一次编写,到处运行”的理念。 1. **JVM...

    JVM+学习笔记资源合集

    JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。 JVM一直是java知识里面进阶阶段的重要部分,如果希望在java领域研究的更深入,则JVM则是如论如何也避开不了的话题,本系列试图通过...

    java之jvm学习笔记十而(访问控制器的栈校验机制)

    本文将深入探讨“访问控制器的栈校验机制”,这是JVM安全模型的重要组成部分。 栈校验机制是JVM在执行字节码时进行的一种静态类型检查。当方法调用、字段访问或数组操作等指令被执行时,JVM会检查操作数栈中的数据...

    java之jvm学习笔记十二(访问控制器的栈校验机制)

    本篇学习笔记将深入探讨这一主题,主要关注Java字节码的执行过程以及如何通过栈校验来防止非法操作。 Java字节码是由Java编译器生成的中间代码,它在JVM上运行前会经过类加载器的验证,其中栈校验是验证的一部分。...

    java之jvm学习笔记十而(访问控制器的栈校验机制)-步骤2源码

    本篇学习笔记将深入探讨这一机制,主要聚焦于步骤2的源码分析。在Java的世界里,类型安全至关重要,尤其是在多线程环境下,防止非法的类型访问和操作能避免潜在的安全风险和程序崩溃。 栈校验机制主要是为了执行...

    JVM内存管理学习笔记

    《JVM内存管理学习笔记》 在Java世界中,JVM(Java Virtual Machine)是运行所有Java应用程序的核心。深入理解JVM内存管理对于优化程序性能、预防和解决内存泄漏问题至关重要。本文将从JVM内存模型、内存区域划分、...

    JVM性能学习笔记思维导图

    本文将根据"JVM性能学习笔记思维导图"的主题,详细阐述JVM的主要组成部分,性能调优的关键点以及相关的工具与实践策略。** 1. **JVM结构与内存模型** - **类装载器(ClassLoader)**:负责加载类文件,确保类在运行...

    黑马JVM学习笔记二

    本文将深入探讨JVM的内存结构,特别是程序计数器、虚拟机栈、本地方法栈、堆内存以及它们在多线程环境下的工作原理。 程序计数器是JVM内存结构的一部分,它是一个非常小但至关重要的组件。程序计数器用于存储即将...

    学习jvm笔记.zip

    总结,学习JVM对于深入理解Java应用程序的运行机制至关重要。通过掌握类加载、内存管理、执行引擎的工作原理,以及垃圾回收和性能优化的方法,开发者能更好地编写高效、稳定的Java程序。同时,熟练运用JVM监控工具,...

    jvm-study:jvm学习笔记

    本学习笔记旨在全面解析JVM的工作原理,涵盖内存管理、类加载机制、垃圾收集、性能调优等多个关键领域,帮助读者从基础到深入地掌握JVM。 1. **JVM结构与运行过程** - JVM由类装载器、运行时数据区、执行引擎、...

Global site tag (gtag.js) - Google Analytics