`
yesjavame
  • 浏览: 691040 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

为什么对象被new 以后在执行dup操作?

阅读更多

为什么对象被new 以后在执行dup操作?
今天有个朋友问我,为什么一个new一个对象的指令在new后面紧跟的是dup操作?他说搜了可能找到的
搜索引擎都找不到答案,包括翻了<<深入JAVA虚拟机指令>>这本书也没有任何说明.

我们先来看看为dup指令的作用,dup指令可以复制栈顶的一个字再压入栈,也就是把栈顶的内容做个备份.
大家知道,JAVA/CLR是完全基于栈的实现,任何操作都是入栈出栈,没有任何寄存器,所以如果要对某一操作
数做两次连续操作,那就要复制两次栈顶操作数,比如:
int x;
int y = x = 2;
当常数2被压入栈顶后,它要连续两次store到变量x和y,所以这里编译后肯定有一个dup操作:

bipush 20
dup
istore_1
istore_2
如果不做dup操作,那么istore_1将20存到内存中的x后,再istore_2要么没有操作数,要么是一个其它的操作数.
当然这在编译时对连续操作已经做dup操作了,所以不会真的出现这个情况.
那么new 指令后,为什么一定要dup操作呢?
因为java代码的new操作编译为虚拟机指令后,虚拟机指令new在堆上分配了内存并在栈顶压入了指向这段内存的
地址供任何下面的操作来调用,但是在这个操作数被程序员能访问的操作之前,虚拟机自己肯定要调用对象的
<init>方法,也就是如果程序员做一个 Type a = new Type();其实要连续两次对栈顶的操作数进行操作.其中一
次是虚拟机内部自动调用的,这种情况是99%以上存在的,而java 编译器是一种聪明的编译器,所以只要有new操作
就优化为将对象的地址操作数DUP,第一次调用invokespecial <init>时会弹出一个,下面一个留给对该对象访问
的操作,即使你的代码是:new Type();没有任何引用.有些虚拟机也会先dup(不同版本编译结果不同),然后<init>时弹出

一个操作数,后面会立即pop掉被复制的那个操作数.这样的做目的是为了编译优化.

有人说那可以直接从栈顶先store到内存中,需要操作的时候再load到栈顶啊,注意再没有<init>操作这前对象对于

程序员是不可见的,否则就会访问到残废的对象,所以只能是先<init>然后才能store到内存中.这两步操作的操作数必须都直接是原来已经存在栈中的,所以只能是dup.

分享到:
评论

相关推荐

    java虚拟机指令dup详解

    从上面的例子中可以看到,dup 指令在 new 指令下面生成,这是因为实例的初始化方法肯定需要用到一次,然后第二个留给程序员使用,例如给变量赋值,抛出异常等。如果我们不用,那编译器也会生成 dup 指令,在初始化...

    《剑指offer》Java创建对象的五种方式.pdf

    在Java编程中,创建对象是程序执行的基本操作。根据标题和描述,我们将详细探讨Java创建对象的五种主要方式。 1. **使用`new`关键字创建对象** 这是最常见的创建对象的方式,通过调用类的构造器来实例化对象。例如...

    对象由生到死的一些过程.doc

    1. **内存分配**:当使用`new`关键字创建对象时,JVM(Java虚拟机)首先会在堆内存中为对象分配空间。这个过程通常涉及到线程安全的内存分配,以防止多个线程同时操作同一块内存。 2. **复制操作**:`dup`指令用于...

    Java虚拟机(字节码介绍)1

    对象创建和操作的指令包括new用于创建类实例,newarray、anewarray和multianewarray分别用于创建单维、多维数组和复杂类型的数组。访问字段的指令如getfield、putfield处理实例字段,getstatic、putstatic处理静态...

    JVM指令查询手册.pdf

    对象操作指令涉及创建对象(如`new`),访问和调用方法(如`invokevirtual`,`invokespecial`),以及字段访问(如`getfield`, `putfield`)。数组操作指令如`iaload`加载数组中的int元素,`iastore`存储int元素到...

    JVM与性能优化知识点整理.pdf

    大多数对象都是在Eden区创建的,当Eden区满时,将会触发Minor GC,Eden区和其中一个Survivor区中的对象会被复制到另一个Survivor区中,而原Survivor区则被清空。 - **老年代**:存放长期存活的对象。当对象在新生代...

    JVM指令手册_jvm指令手册_

    3. **算术运算指令**:包括加减乘除等基本数学运算,如`iadd`表示整数加法,`imul`表示整数乘法,这些指令在执行计算时会使用操作数栈。 4. **类型转换指令**:Java是一种强类型语言,不同数据类型的转换需要特定...

    jvm-java字节码规则.pdf

    `new`指令用于创建新对象,`checkcast`指令用于检查类型转换是否有效,`getfield`和`putfield`用于获取和设置对象字段的值,`getstatic`和`putstatic`用于获取和设置静态字段的值,`instanceof`指令用于检查对象是否...

    java常量池分析.pdf

    `new`指令用于在堆上创建一个新的`String`对象,`dup`指令复制栈顶的引用,`ldc`指令再次从常量池获取"haha"的引用,`invokespecial`调用`String`构造器来初始化新对象,最后`astore_1`将新对象的引用存储到变量`s`...

    JVM指令集.docx

    10. **对象创建和初始化**:`new`指令用于创建新的对象实例,` anewarray `用于创建数组,`dup`复制栈顶的值,`invokenonvirtual`调用接口方法。 JVM指令集的设计使得Java代码能够在任何支持JVM的平台上运行,实现...

    Java字节码揭秘

    这意味着即使两个类来自同一个类文件,但如果它们被不同的类加载器加载,那么这两个类也将被视为不同的类。 以上就是关于Java字节码及其相关概念的详细介绍,涵盖了从Java体系结构到字节码指令的具体例子,以及类...

    JVM:Pedersen博士的CS326编程语言代码

    在JVM中,对象的创建通过`new`指令完成,字段访问通过`getfield`和`putfield`指令,方法调用则通过`invoke`系列指令实现。此外,还要理解类加载机制,包括类加载器和双亲委托模型,以及垃圾回收(GC)的基础,如对象...

    OpenSSL接口说明文档

    这是在使用前必须执行的操作。 - **BN_CTX_free** `void BN_CTX_free(BN_CTX *c);` 释放`c`指向的`BN_CTX`结构体占用的内存,并将`c`设置为`NULL`。 ##### 3. 复制与交换函数 这些函数提供了复制或交换`...

    类实例化顺序讲解 附阿里巴巴一道笔试题

    1. **new对象底层字节码指令分析**:在Java字节码中,`new`指令用于创建一个对象,`dup`用于复制对象引用,`invokespecial`调用构造函数,`pop`用于弹出栈顶的引用,如果有多次`new`,则需要重复这些步骤。...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    简单来说是本身可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。 常见的数据模型 1. 层次结构模型: 层次结构模型实质上是一种有根结点的定向有序树,IMS...

    python 模块详细列表

    通过`os`模块,开发者能够执行文件和目录的操作,如创建文件夹、删除文件、获取当前工作目录等。 ##### 导入方式: ```python import os ``` ##### 常用属性与方法: - **常量**: - `os.EX_*`:一系列用于表示...

    简要说明Ruby中的迭代器

    `each`迭代器总是伴随着一个块,这个块会在每次迭代时被执行,其中的变量`i`会依次取数组`ary`的每一个元素。因此,`each`主要用于简单地遍历并处理集合中的所有元素,而不仅仅是输出它们。 接下来是`collect`迭代...

    sqlserver2005自动创建数据表和自动添加某个字段索引

    在SQL Server 2005中,开发人员经常需要通过编程方式动态地创建数据库表以及为特定字段添加索引,特别是在构建应用程序时。这有助于确保数据库结构与应用程序需求同步,并且能够灵活应对需求变化。本篇文章将详细...

    软件工程工资管理系统

    用户在员工信息管理模块对该员工的工资等级进行输入以后,在工资汇总模块会自动对员工工资进行汇总。用户可以打印出工资汇总表,打印之前可以通过打印预览功能进行打预览。 2.2数据字典 该软件的数据库由下述四张...

Global site tag (gtag.js) - Google Analytics