有老哥知道为什么吗?有点晕了。
1
ignor 2021-03-17 19:14:53 +08:00 via Android
一些明显没有意义的语句被编译器优化掉了
|
2
codingbody OP @ignor #1 我看了编译后字节码,一样的。
|
3
codingbody OP 这是图 1 和 图 2 字节码对比:
![192031]( https://image.yuhaowin.com/2021/03/17/192031.png) |
4
ignor 2021-03-17 20:59:04 +08:00 via Android
运行时也会优化的,关掉 JIT 优化试试
|
5
ignor 2021-03-17 20:59:39 +08:00 via Android
当然,最好是绕开这个问题
|
6
zhzy0077 2021-03-17 23:12:02 +08:00
Java 不是 C/Rust 这种编译到机器指令的语言,就算是字节码最后也是 JVM 解释执行的,这里是一个很明显的常量推导,JVM 没理由再把那个 if 留着。最好别纠缠在这种优化的问题上,你的实际场景是什么?
|
7
yannxia 2021-03-17 23:19:20 +08:00
图二的字节码反编译之后如下
<a href="https://sm.ms/image/PXaW46JO8GZgTfd" target="_blank"><img src="https://i.loli.net/2021/03/17/PXaW46JO8GZgTfd.png" ></a> |
8
Xuanyian 2021-03-17 23:39:22 +08:00
@codingbody continue 那句是 L8,从字节码上来看根本到不了 L8 。一旦 JVM 优化它就会被删掉。所以关键是会不会触发 JVM 的优化。你可以试试看把 value 设成“11”然后把 key 设成 null,这样的话 JVM 还是会触发优化。你应该还是不可以进到断点。
你也可以把 key 改成 boolean,只要他是 true,就会在 OR 条件下触发优化,value 是什么都无所谓。 这里边应该是两层优化,一个是生成字节码时对 continue 的优化,另一个是 JVM 对 IF 语句的优化。 |
9
codingbody OP @zhzy0077 实际的场景是,我有一些 k=v 的字符串,需要对其中的 k 或 v 为空的过滤掉,测试的时候发现不是所有满足过滤条件的数据都会进去 continue 断点。
|
10
lxilu 2021-03-18 00:20:26 +08:00 via iPhone
整个 main 都会被 JIT 抹掉吧
|
11
des 2021-03-18 00:45:18 +08:00 via iPhone
问一下,debug 模式 jvm 也会进行优化的吗?
|
12
967182 2021-03-18 09:30:15 +08:00
JIT 这种没毛线用的语句老子才不给你跑呢!
|
13
zhzy0077 2021-03-18 10:59:18 +08:00
@codingbody 这里你真要测最简单就是从文本或者 io 输入这两个字符串 jvm*一般*是不会对预测不到的变量做优化的。
|
14
codingbody OP @zhzy0077 #13 真实业务场景的确是读取的两个值,在 debug 的时候发现有些情况下(如:读取的 key,value 都是空)无法进入 continue 断点。
|