操作数

5.3.8 栈帧

不问归期 提交于 2019-12-06 10:56:45
栈帧由三部分组成:局部变量区,操作数找和帧数据区。局部变量区和操作数栈的大小要 视对应的方法而定,它们是按字长计算的。编译器在编译时就确定了这些值并放在class文件中。 而帧数据区的大小依赖于具体的实现。 当虚拟机调用一个Java方法时,它从对应类的类型信息中得到此方法的局部变量区和操作数 栈的大小,并据此分配栈帧内存,然后压人Java栈中。 局部变量区 Java栈帧的局部变量区被组织为一个以字长为单位、从0开始计数的数组。字 节码指令通过从0开始的索引来使用其中的数据。类型为int、float, reference和returnAddress的值在数组中只占据一项,而类型为byte、short和char的值在存人数组前都将被转换为int值,因而同样占据一项。但是类型为long和double的值在数组中却占据连续的两项。 在访问局部变量中的long和double值的时候,指令只需指出连续两项中第一项的索引值。例 如某个long值占据第3、4项,那么指令会取索引为3的long值。局部变量区的所有值都是字对齐 的,long和double这样占据两项数组元素的值同样可以起始于任何索引。 局部变量区包含对应方法的参数和局部变量。编译器首先按声明的顺序把这些参数放入局 部变量数组。图5-9描绘了下面两个方法的局部变量区。 我们注意到,在源代码中的byte、short.

5.3.10 执行引擎

穿精又带淫゛_ 提交于 2019-12-06 10:56:40
任何Java虚拟机实现的核心都是它的执行引擎。在Java虚拟机规范中,执行引擎的行为使用 指令集来定义。对于每条指令,规范都详细规定了当实现执行到该指令时应该处理什么,但是却对如何处理言之甚少。在前面的章节中提到过,实现的设计者有权决定如何执行字节码:实 现可以采取解释、即时编译或直接用芯片上的指令执行,还可以是它们的混合,或任何你能想 到的新技术。 和本章幵头提到的对“Java虚拟机”这个术语有三种不同的理解一样,“执行引擎”这个术 语也可以有三种理解:一个是抽象的规范,一个是具体的实现,另一个是正在运行的实例,抽象规范使用指令集规定了执行引擎的行为。具体实现可能使用多种不同的技术——包括软件方 面、硬件方面或数种技术的集合。作为运行时实例的执行引擎就是一个线程。 运行中Java程序的每一个线程都是一个独立的虚拟机执行引擎的实例。从线程生命周期的开始到结束,它要么在执行字节码,要么在执行本地方法。一个线程可能通过解释或者使用芯片 级指令直接执行字节码,或者间接通过即时编译器执行编译过的本地代码。Java虚拟机的实现可 用一些对用户程序不可见的线程,比如垃圾收集器。这样的线程不需要是实现的执行引擎的 实例。所有属于用户运行程序的线程,都是在实际工作的执行引擎。 指令集方法的字节码流是由Java虚拟机的指令序列构成的,每一条指令包含一个单字节的操作码,后面跟随0个或多个操作数

JVM 栈和栈帧

房东的猫 提交于 2019-12-06 10:39:21
前情提要 对于没有深度递归的函数来说,无需担心 上篇文章 中的算法。当知道正在处理数据集有限时,我会使用这种简单的基本递归形式。由于你并不知道在应用程序中会处理多少数据,因此确保你的递归算法是 尾递归(tail-recursive) 就变得十分重要,否则你将可能遇到讨厌的 StackOverflowError . 举个例子,如果你用一个较大的list来运行上文中的sum函数,将出现 StackOverflowError ,这与我们开发出稳定、出色的函数式程序相悖。 object RecursiveSum extends App { def sum(list: List[Int]): Int = list match { case Nil => 0 case x :: xs => x + sum(xs) } val list = List.range(1, 10000) // MUCH MORE DATA val x = sum(list) println(x) } 具体到底需要多少数字才能引发 StackOverflowError,这取决于JVM的设置。Java默认的Stack大小是1024kb,这是非常小的内存。 关于尾递归,下篇文章我会继续讲解,本文我想讨论下JVM Stack 和 Stack frames。如果你不熟悉这些概念,本文有助于你理解,同时有益于debug

Mysql

社会主义新天地 提交于 2019-12-06 10:23:39
总结;左连接,from 表1 left join 表2 on .. 连接条件 left是关键字 相应的位置会自己补null. 右连接,from 表1 right join 表2 on .. 跟左连接一样 全连接 , from 表 1 full join 表 2 on .. 子查询 子查询就是把一个查询的结果当作另一个查询的条件。 in的基本语法形式为: where 操作数 in (值1,值2, ....) 则in子查询就是: where 操作数 in ( 列子查询 ); 含义: 表示该操作数(字段值) 等于 该子查询的其中任意一个只,就算满足条 件。 来源: https://www.cnblogs.com/m9m941102/p/11977305.html

C#中 ??、 ?、 ?: 、?.、?[ ] 问号各组合含义

孤人 提交于 2019-12-06 08:39:14
1. 可空类型修饰符(?) 引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空。 例如:string str=null; 是正确的,int i=null; 编译器就会报错。 为了使值类型也可为空,就可以使用可空类型,即用可空类型修饰符"?“来表示,表现形式为"T?” 例如:int? 表示可空的整形,DateTime? 表示可为空的时间。 T? 其实是System.Nullable(泛型结构)的缩写形式, 也就意味着当你用到T?时编译器编译时会把T?编译成System.Nullable的形式。 例如:int?,编译后便是System.Nullable的形式。 2. 三元(运算符)表达式(?: ) 例如:x?y:z 表示如果表达式x为true,则返回y; 如果x为false,则返回z,是省略if{}else{}的简单形式。 3. 空合并运算符(??) 用于定义可空类型和引用类型的默认值。 如果此运算符的左操作数不为null,则此运算符将返回左操作数,否则返回右操作数。 例如:a??b 当a为null时则返回b,a不为null时则返回a本身。 空合并运算符为右结合运算符,即操作时从右向左进行组合的。 如,“a??b??c”的形式按“a??(b??c)”计算。 4.NULL检查运算符(?.)   例如我们要获取一个Point序列的第一个点的X坐标,第一感觉会这么写: int

java运算符

落爺英雄遲暮 提交于 2019-12-06 07:45:14
Java 运算符 计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 其他运算符 算术运算符 算术运算符用在数学表达式中,它们的作用和在数学中的作用一样。下表列出了所有的算术运算符。 表格中的实例假设整数变量A的值为10,变量B的值为20: 操作符 描述 例子 + 加法 - 相加运算符两侧的值 A + B等于30 - 减法 - 左操作数减去右操作数 A – B等于-10 `*` 乘法 - 相乘操作符两侧的值 A * B等于200 / 除法 - 左操作数除以右操作数 B / A等于2 % 取模 - 左操作数除以右操作数的余数 B%A等于0 ++ 自增 - 操作数的值增加1 B++ 或 ++B 等于 21 -- 自减 - 操作数的值减少1 B-- 或 --B 等于 19 实例 下面的简单示例程序演示了算术运算符。复制并粘贴下面的Java程序并保存为 Test.java 文件,然后编译并运行这个程序: public class Test { public static void main(String args[]) { int a = 10; int b = 20; int c = 25; int d = 25; System.out

C++ 类型转换

扶醉桌前 提交于 2019-12-06 04:33:09
类型转换: 在 C++ 中, 如果两种类型相关联, 如果程序需要一种类型的运算对象时,可以用另一种关联类型的对象或值来代替。 也就是说,这两种类型可以互相转换, 即两种类型是关联的。 int ival = 3.541+ 3; 编译器会警告 运算会损失精度 。 隐式类型转换: C ++ 不会将两个数直接相加, 而是先根据类型转换规则 将对象转换成统一的类型后再求值。 隐式类型转换: 这种类型转换 是编译器 自动执行, 不需要程序员介入 。 表达式中先把 int 转换成 double , 计算结果为 double , 然后在把 double 转换成 int 赋值给变量 ival 隐式转换的情况: 下面 编译器会自动转换对象的 类型。 大多数表达式中, 比 int 小的类型首先提升成较大的整数类型 。 作为 条件 的表达式 中, 非布尔值转换成布尔值 初始化中, 如果算术运算或关系运算的对象 有 多种类型, 需要转换成同一种类型 C++ 常规类型自动类型转换规则 ( 1 )如果有一个操作数的类型是 long double ,则将另一个操作数转换为 long double 。 ( 2 )否则,如果有一个操作数的类型是 double ,则将另一个操作数转换为 double 。 ( 3 )否则,如果有一个操作数的类型是 float ,则将另一个操作数转换为 float 。 ( 4 )否则

JavaSE基础(五)--Java运算符

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-06 01:12:39
Java 运算符 计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 其他运算符 算术运算符 算术运算符用在数学表达式中,它们的作用和在数学中的作用一样。下表列出了所有的算术运算符。 表格中的实例假设整数变量A的值为10,变量B的值为20: 操作符 描述 例子 + 加法 - 相加运算符两侧的值 A + B 等于 30 - 减法 - 左操作数减去右操作数 A – B 等于 -10 * 乘法 - 相乘操作符两侧的值 A * B等于200 / 除法 - 左操作数除以右操作数 B / A等于2 % 取余 - 左操作数除以右操作数的余数 B%A等于0 ++ 自增: 操作数的值增加1 B++ 或 ++B 等于 21(区别详见下文) -- 自减: 操作数的值减少1 B-- 或 --B 等于 19(区别详见下文) 实例 下面的简单示例程序演示了算术运算符。复制并粘贴下面的 Java 程序并保存为 Test.java 文件,然后编译并运行这个程序: 实例 public class Test {   public static void main ( String [ ] args ) {     int a = 10 ;     int b = 20 ;   

JVM(二) 栈内存结构

孤街醉人 提交于 2019-12-05 20:43:47
栈内存是描述java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、返回出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。栈帧(Frame)是用来存储数据和部分过程结果的数据结构,同时也被用来处理动态链接(Dynamic Linking)、方法返回值和异常分派(Dispatch Exception)。栈帧随着方法调用而创建,随着方法结束而销毁——无论方法是正常完成还是异常完成(抛出了在方法内未被捕获的异常)都算作方法结束。 局部变量表 局部变量表(Local Variables Table)也可以称之为本地变量表,它包含在一个独立的栈帧中。顾名思义,局部变量表主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类原始数据类型、对象引用(reference),以及returnAddress类型。局部变量表所需的容量大小在编译期就可以被完全确定下来,并保存在方法的Code属性中。大家思考一下,既然方法体内定义的局部变量是存储在栈帧中的局部变量表里的,那么原始数据类型的成员变量的值是否也存储在局部变量表中呢?其实如果是定义在方法体外的成员变量,不止是作用域发生了变化,更重要的是,其值也并非还是存储在局部变量表里,而是存储在对象内存空间的实例数据中

程序员需要了解的硬核知识之汇编语言(一)

会有一股神秘感。 提交于 2019-12-05 19:27:07
之前的系列文章从 CPU 和内存方面简单介绍了一下汇编语言,但是还没有系统的了解一下汇编语言,汇编语言作为第二代计算机语言,会用一些容易理解和记忆的字母,单词来代替一个特定的指令,作为高级编程语言的基础,有必要系统的了解一下汇编语言,那么本篇文章希望大家跟我一起来了解一下汇编语言。 汇编语言和本地代码 我们在之前的文章中探讨过,计算机 CPU 只能运行本地代码(机器语言)程序,用 C 语言等高级语言编写的代码,需要经过编译器编译后,转换为本地代码才能够被 CPU 解释执行。 但是本地代码的可读性非常差,所以需要使用一种能够直接读懂的语言来替换本地代码,那就是在各本地代码中,附带上表示其功能的英文缩写,比如在加法运算的本地代码加上 add(addition) 的缩写、在比较运算符的本地代码中加上 cmp(compare) 的缩写等,这些通过缩写来表示具体本地代码指令的标志称为 助记符 ,使用助记符的语言称为 汇编语言 。这样,通过阅读汇编语言,也能够了解本地代码的含义了。 不过,即使是使用汇编语言编写的源代码,最终也必须要转换为本地代码才能够运行,负责做这项工作的程序称为 编译器 ,转换的这个过程称为 汇编 。在将源代码转换为本地代码这个功能方面,汇编器和编译器是同样的。 用汇编语言编写的源代码和本地代码是一一对应的。因而,本地代码也可以反过来转换成汇编语言编写的代码