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

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

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

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值