java中double强制转换int引发的OOM问题记录

 更新时间:2024年10月23日 09:45:38   作者:冷雨夜中漫步  
这篇文章主要介绍了java中double强制转换int引发的OOM问题记录,本文给大家分享问题排查过程,感兴趣的朋友跟随小编一起看看吧

问题代码

最近出现了一次OOM问题,问题代码如下

public void prcess(double total, int step) {
	int num = (int) Math.floor(total / step);
	while (num-- > 0) {
		doSomething(); // 普通方法,占用内存不大
	}
}

根据单步步长step将total值划分后,然后进行处理。然后日志中发现堆栈在doSomething()时报错OOM,抛出java.lang.OutOfMemoryError。确认过doSomething()方法不会占用过大的内存,那为何会发生问题?

排查过程

怀疑num过大导致,查看入参total为合理值,但是step是取配置值,配置未配置时默认为0,则问题代码为int num = (int) Math.floor(total / step);,这里step为0,Math.floor(total / step) = Infinity,强制转为int后得到值为2147483647。一直在处理此处的逻辑导致内存增长,进而发生OOM

double特殊值与强制转换

java语言中浮点运算存在两个值:NaN与Infinity

NaN

Not-a-Number,非数字值,数学上0/0是无意义的,java在浮点运算中实现了NaN,定义为0.0/0.0。NaN有如下几个特点:

NaN与任何数字都不相等,NaN与其本身也不相等

System.out.println(Double.NaN == Double.NaN); // false
System.out.println(Double.NaN == 0.0/0.0); // false
System.out.println(Double.NaN == 0.0); // false

使用Double.isNaN或Float.isNaN确认是否为NaN

System.out.println(Double.isNaN(0.0/0.0));  // true
System.out.println(Float.isNaN(0.0f/0.0f));  // true

NaN与任何数字比较都是false

System.out.println(Double.NaN > 0.0); // false
System.out.println(Double.NaN < 0.0); // false

Infinity

无限,分为正无限与负限小,定义为一个非0数字除以0。

有如下几个特点:

正无限与负无限定义

public static final double POSITIVE_INFINITY = 1.0 / 0.0;
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;

无限与任何非无限非0数字运算仍为无限

System.out.println(Double.POSITIVE_INFINITY + Double.MAX_VALUE); // Infinity
System.out.println(Double.POSITIVE_INFINITY - Double.MAX_VALUE); // Infinity
System.out.println(Double.POSITIVE_INFINITY * Double.MAX_VALUE); // Infinity
System.out.println(Double.POSITIVE_INFINITY / Double.MAX_VALUE); // Infinity
System.out.println(Double.NEGATIVE_INFINITY + Double.MIN_VALUE); // -Infinity
System.out.println(Double.NEGATIVE_INFINITY - Double.MIN_VALUE); // -Infinity
System.out.println(Double.NEGATIVE_INFINITY * Double.MIN_VALUE); // -Infinity
System.out.println(Double.NEGATIVE_INFINITY / Double.MIN_VALUE); // -Infinity

无限与0运算为无限或NaN

System.out.println(Double.POSITIVE_INFINITY / 0); // Infinity
System.out.println(Double.POSITIVE_INFINITY * 0); // NaN
System.out.println(Double.NEGATIVE_INFINITY / 0); // -Infinity
System.out.println(Double.NEGATIVE_INFINITY * 0); // NaN

负无限与正无限运算为无限或NaN

System.out.println(Double.POSITIVE_INFINITY + Double.NEGATIVE_INFINITY); // NaN
System.out.println(Double.POSITIVE_INFINITY - Double.NEGATIVE_INFINITY); // Infinity
System.out.println(Double.NEGATIVE_INFINITY + Double.POSITIVE_INFINITY); // NaN
System.out.println(Double.NEGATIVE_INFINITY - Double.POSITIVE_INFINITY); // -Infinity
System.out.println(Double.POSITIVE_INFINITY * Double.NEGATIVE_INFINITY); // -Infinity
System.out.println(Double.POSITIVE_INFINITY / Double.NEGATIVE_INFINITY); // NaN
System.out.println(Double.NEGATIVE_INFINITY * Double.POSITIVE_INFINITY); // -Infinity
System.out.println(Double.NEGATIVE_INFINITY / Double.POSITIVE_INFINITY); // NaN

无限强制转换为整形会有精度丢失

System.out.println((int)Double.POSITIVE_INFINITY); // Integer.MAX_VALUE
System.out.println((int)Double.NEGATIVE_INFINITY); // Integer.MIN_VALUE
System.out.println((long) Double.POSITIVE_INFINITY); // Long.MAX_VALUE
System.out.println((long)Double.NEGATIVE_INFINITY); // Long.MIN_VALUE

到此这篇关于java中double强制转换int引发的OOM问题的文章就介绍到这了,更多相关java强制转换double转int内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现FIFO任务调度队列策略

    Java实现FIFO任务调度队列策略

    在工作中,很多高并发的场景中,我们会用到队列来实现大量的任务请求。当任务需要某些特殊资源的时候,我们还需要合理的分配资源,让队列中的任务高效且有序完成任务。本文将为大家介绍通过java实现FIFO任务调度,需要的可以参考一下
    2021-12-12
  • SpringCloud修改Feign日志记录级别过程浅析

    SpringCloud修改Feign日志记录级别过程浅析

    OpenFeign源于Netflix的Feign,是http通信的客户端。屏蔽了网络通信的细节,直接面向接口的方式开发,让开发者感知不到网络通信细节。所有远程调用,都像调用本地方法一样完成
    2023-02-02
  • httpclient的disableConnectionState方法工作流程

    httpclient的disableConnectionState方法工作流程

    这篇文章主要为大家介绍了httpclient的disableConnectionState方法工作流程源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 常用的Java数据结构知识点汇总

    常用的Java数据结构知识点汇总

    这篇文章主要介绍了常用的Java数据结构知识点汇总,数据结构分线性数据结构和非线性数据结构,下面对此作详细介绍,需要的小伙伴可以参考一下,希望对你的学习或工作有所帮助
    2022-03-03
  • myatisplus的saveOrUpdate的提交总是update问题

    myatisplus的saveOrUpdate的提交总是update问题

    这篇文章主要介绍了myatisplus的saveOrUpdate的提交总是update问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java使用utf8格式保存文本文件的方法

    Java使用utf8格式保存文本文件的方法

    这篇文章主要介绍了Java使用utf8格式保存文本文件的方法,涉及Java针对字符流编码操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • SpringBoot自定义Starter实现流程详解

    SpringBoot自定义Starter实现流程详解

    SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰
    2022-09-09
  • java提高篇(二三)-----HashMap详解

    java提高篇(二三)-----HashMap详解

    HashMap基于哈希表的 Map 接口的实现,本篇文章主要讲诉了java中HashMap,有兴趣的可以了解一下。
    2016-11-11
  • Java tomcat手动配置servlet详解

    Java tomcat手动配置servlet详解

    这篇文章主要为大家介绍了tomcat手动配置servlet,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • Mybatis之解决collection一对多问题(显示的结果没有整合到一起)

    Mybatis之解决collection一对多问题(显示的结果没有整合到一起)

    这篇文章主要介绍了Mybatis之解决collection一对多问题(显示的结果没有整合到一起),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03

最新评论