锁定老帖子 主题:一个隐形的java int溢出
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-08-30
笔者最近在做一个类SNS的项目,其中使用了MongoDB进行Feed信息存储,并使用定时器删除过期信息。 定时器的时间变量为60天,设定 private long msgInvalidDue = 60 * 24 * 3600 * 1000; 故事的发生: 在项目上线的某天,突然发现,2周前的数据丢失了,遍历了程序,没发现逻辑问题,甚至开始当心MongoDB造成的数据丢失(业内也是发生过的)。 笔者当时纠结啊~~ 但第二天又发现数据的丢失是持续而且有规律的,于是,焦点便集中到了“定时删除任务”。左查右查没发现问题,只能一步一步的进行跟踪调试。。。。 故事的结局: 很难令人想象,问题就出现在msgInvalidDue这个long型常量上。按道理它的值应该是5184000000L的(表示60天的时间),但是它实际值却是 889032704(大约10天时间),why???? 居然是int在计算过程中的溢出~~~~太隐晦的bug了~~正确的写法 private long msgInvalidDue = 60 * 24 * 3600L * 1000; 任意一个常量上加L,转long型就OK了,坑爹哇~~~这回真是阴沟里翻船了~~ 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-08-30
哈哈,这种bug是挺难查的。不过可以借助一些工具来扫一下,比如findbugs,这样的bug应该可以避免。
|
|
返回顶楼 | |
发表时间:2011-08-30
不知道什么时候也触发过此bug(最可能的是算时间: 24 * 60 * 60 * 1000).
所以现在一直习惯性的这样写:long l = 1L * XXX |
|
返回顶楼 | |
发表时间:2011-08-30
最后修改:2011-08-30
这个bug经典,effective java 里面有讲到这一点,
Java的隐式转换确实问题很多。 1/4+3/4 =? 的问题虽然很基础,但是很重要。 类似的问题,算术计算方面的,谁来总结一下。 |
|
返回顶楼 | |
发表时间:2011-08-30
java解惑里的谜题三也讲到了这个问题,以int运算来执行,运算完成后提升为long类型,但此时计算已溢出。
|
|
返回顶楼 | |
发表时间:2011-08-30
又长见识了……这个问题还真没遇到……
|
|
返回顶楼 | |
发表时间:2011-08-30
小问题大BUG,血的教训告诉我们...没事应该注视下基础
|
|
返回顶楼 | |
发表时间:2011-08-30
前车之覆后车之鉴,LZ的教训值得铭记啊
PS:居然有人投新手贴,抱不平 |
|
返回顶楼 | |
发表时间:2011-08-30
确实经典,看来要好好研究一下java虚拟机原理了。
|
|
返回顶楼 | |
发表时间:2011-08-30
多谢楼主,小弟受教了…
在学习的时候会看到这样的例子之类的,但是在实际工作中很多时候容易忽略… |
|
返回顶楼 | |