Java VM规范有感

较为仔细地看了JavaVM规范,还是颇有收获的。

[b]关于线程:[/b]
1. 每个线程使用独立的栈空间,栈空间的大小在实现上实际上有两种模式:1)固定大小的; 2)可动态扩容的模式(这一点有点出乎我意料之外,这种栈一般来说都不允许动态扩展的),具体支持哪种模式与实现者有关(不过java.lang.Thread类并不支持指定一个最大最小值之类的参数),因此个人认为对栈空间的扩容,支持的还是比较有限的。

[b]关于指令:[/b]
1. Java的指令占用空间为一个字节,因此Java的指令上限为256个

2. 指令是带有数据类型信息的(比如iload的语义是将某个整数压入操作数栈),但是指令和数据类型并不是独立的,有些指令只为特定的一个或者几个数据类型准备的(原因是因为No.1,指令必须尽可能的精简,否则不够用)

3. 由于No.2,导致相同的代码,不同的数据类型,最终生成的指令会有一定的差异,甚至是比较大的差异,比如iinc指令是做某整数的++操作,但是并没有linc(针对Long的++操作),因此
(int index++与 long index++生成指令并不相同,前者很简单,只有一个iinc,而后者则会翻译成类似于index = index + 1的指令: lconst_1 --> lload --> ladd三条指令),这一点很有趣。

4. 很多数据类型,实际上Java支持的很有限,比如byte,short,boolean对于大多数指令而言,是直接翻译成为int类型的(所以不要以为byte.short占空间就那么少,其实是和int差不多的)
5. 一般来说使用long,fload,double等类型生成的指令要比int长的比较多,但是byte,short,boolean和int一般来说没有什么差别

6. 以前看开源代码,不知道为什么大家会吧 int i ; if(i<=1) 写成int i; if(i<2),只是自己也照抄了,现在知道了,条件跳转并没有大于等于、小于等于的指令,所以前面的写法实际上会多生成好几条指令(也许是我太追求完美了,二者执行时间并不会有什么差异,但是在没有付出额外成本的情况下,能提高效率的地方还是要提高,这个是一个程序员的素养,我认为)

7.this指针:实际上编译的时候会将this作为一个隐含的参数传入目标方法,但是static方法除外,所以实际上static方法和普通方法比较,static方法会少用一个参数(this)

[b]关于反编译:[/b]
实际上反编译不能完全还原源代码的信息,比较典型的信息有:
1. 循环信息(for,while,dowhile等)
2. 方法参数名:这就是为什么反编译参数只是将参数名命名为int0,object1等名称
3. 局部变量名:和参数名一样(指令集引用参数和局部变量的时候使用的是变量在
线程栈里面的偏移量的方式引用的,这一点与C语言的编译方式很类似),但是属性名、方法名等使用的都是名称(实际上是维持对常量池的一个索引)
4. 注释信息(这一点比较容易理解,编译的时候如果把注释也编译进去实在没什么用)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值