Java死循环执行InputStream.available()导致CPU占满

记一次InputStream流读取不完整留下的惨痛教训 首先,问问大家下面这段流读取的代码是否存在问题呢?try {// 根据inputStream的长度创建字节数组// 调用read 读取字节数组}实际上的确是有问题的,而且在线上环境结结实实的坑了我们一把。在代码编写过程中,available()方法仅用于估算接收数据的总长度或数据块的长度,不要用于任何需要准确计算的场合,更不要用于开辟一个可以刚好容纳所有数据的缓冲区。对于调用InputStream.read(…),务必进行循环调用,直至返回-1,无论输入数据源是网络数据还是本地文件。 阅读详情

问题详细

发现Java应用服务器常年cpu占满的状态,执行top命令发现是某个java进程占满cpu资源。如果网络请求并发大的话,可能直接导致宕机

具体原因

通过几行linux命令,定位到看如下代码:
InputStream in = null;
in = socket.getInputStream();
int count = 0;
while (count == 0) {
count = in.available();//死循环代码消耗cpu
}
这段代码是处理请求后的响应,希望读到输入流里面总的字节大小,且有时候因为网络原因无法一次读到结果,所以加上while循环,但如果一直读不到,那就麻烦了,死循环可能一直执行下去,或者会执行到超时时间自己断开。无论哪种情况,只要依然要发送请求,给运维人员的感觉就是cpu一直被占满。
注:如何定位到问题代码见补充

解决办法

为避免死循环,需要在适当的时候,break出循环。请看修改后的代码:
InputStream in = null;
in = socket.getInputStream();
int count = 0;
int trytimes =0;
while (count == 0) {
count = in.available();
trytimes++;
if(trytimes>maxCustomTimes && count ==0) {
break;
}
}
log.info("-- trytimes: “+ trytimes+”, – count"+count);
if(count!=0) {
byte[] bs = new byte[count];
… //读取输入流里面的内容
}
注:maxCustomTimes 写到配置里面,我设置的是2000000次如果还读不到输入流,可能真的
不会有什么返回到客户端了,直接跳出循环,跳出后判断输入流里面是否有内容,有的话就读出
来,没有的话忽略,或者再break之前,写一些公共返回,提示操作人员没有收到服务端响应。

补充

如何从占满cpu的进程中找到耗费cup资源多的线程,继而找到线程详细信息定位到java类及发生死循环的代码行?
[步骤1]确定java进程编号
在linux服务器上执行top
找到占满cpu线程的PID(进程编号)
[步骤2]查看java中进程里面线程的占比
top -p 进程号-H
[步骤3]查看线程信息
jstack 进程号 |grep -A 10 线程号(16进制)
注:步骤2和步骤3中的进程号为步骤1找出的进程号;
16进制的线程号从步骤2查到的线程号(10进制)转换而来。具体如何转参考 链接: 如何定位到问题代码.

拓展:网络流中 InputStream.available() = 0 问题探究

Java IO底层原理:从系统调用、零拷贝到生产级日志归档实战 Java IO不是简单的API调用,而是Java虚拟机、操作系统内核与硬件设备三者深度协同的结果。理解其本质需回归I/O基本模型:数据如何在用户空间与内核空间间流动?为何传统BIO在高并发下失效?NIO的Buffer设计如何匹配DMA物理寻址?零拷贝(如transferTo、mmap)又怎样绕过JVM堆内存实现性能跃迁?本文以Linux epoll、ext4 page cache、JVM DirectMemory为技术支点,结合strace/perf/eBPF可观测性工具链,解析FileChannel、Ma 阅读详情

相关推荐

InputStream.available()使用大坑

问题场景:文件下载功能,需要对原来的文件进行读取再输出到文件或浏览器中,会常用到InputStream.available()方法。经历过一次系统功能变更升级,需要将文件先下载到本地再响应出去,发现下载的文件不全 百思不得其解,搜索好久资料,查找得知,以备忘记 这个方法可以在读写操作前先得知数据流里有多少个字节可以读取。 需要注意的是,如果这个方法用在从本地文件读取数据时,一般不会遇到...

DazedMen的博客 8697

new InputStream().available()方法的讲解

====================================================== 案例一: 先看看下面这段代码(有删节) public static String send(String sendurl, String sendText) throws Exception { URL url = null; URLConnection uc = nul...

445822357 1787

大模型备案避坑指南:如何设计符合TC260标准的评估测试题集?

本文深入探讨了如何设计符合TC260标准的大模型评估测试题集,以顺利通过备案。文章从解构标准核心逻辑出发,详细阐述了题集设计的工程化流程、核心原则与常见误区,并提供了模拟真实对抗的高阶测试策略与度量分析方法,旨在帮助企业构建一套能真实反映模型安全水位、有效规避风险的评估体系。

kafka6courier的博客 665

java文件第100bytes处_java.io.FileInputStream.readBytes(Native Method)的无限100%CPU使用率

我正在调试一个程序,每个外部进程有两个线程,这两个线程使用while((i = in.read(buf,0,…))继续读取Process.getErrorStream()和Process.getInputStream() buf.length))> = 0)循环。有时当外部进程由于JVM崩溃而崩溃(参见these hs_err_pid.log files)时,读取该外部进程的stdout /...

weixin_39807541的博客 877

MT4量化交易入门:手把手教你用MQL4编写第一个外汇EA(含完整代码)

本文详细介绍了如何使用MQL4在MT4平台上编写第一个外汇EA,涵盖从开发环境配置到均线交叉策略实现的完整流程。通过手把手教学和完整代码示例,帮助量化交易新手快速掌握外汇自动化交易的核心技术,实现高效的MT4量化交易系统。

mmm90的博客 527

手把手教你用STM32的SPI驱动MCP2517FD实现CAN FD通信(附完整代码)

本文详细介绍了如何使用STM32通过SPI驱动MCP2517FD实现CAN FD通信,涵盖硬件连接、SPI驱动编写、寄存器配置及数据收发实战。提供完整代码示例和常见问题排查指南,帮助开发者快速构建高可靠性的CAN FD通信系统,适用于汽车电子和工业控制等领域。

weixin_30607029的博客 676

由InputStream.available()引发的偶现bug

分析错误使用available()方法的案例,available()不合规使用后果的原因,分析spring boot网络请求中流的原理,分析@RequestBody原理

edui的博客 2739

别再花钱买商业软件了!这4款免费DIC工具,从散斑生成到应变分析全搞定

本文介绍了4款免费开源的DIC(数字图像相关技术)工具,涵盖从散斑生成到应变分析的全流程,帮助用户零成本构建专业级DIC工作流。这些工具在精度、算法透明度和生态整合方面具有优势,适用于材料力学和实验力学研究,可替代昂贵的商业软件。

weixin_42525369的博客 169

inputStream.avaliable()方法网络操作读取不全BUG

用InputStream.available()方法,这个方法可以在读写操作前先得知数据流里有多少个字节可以读取。 需要注意的是,如果这个方法用在从本地文件读取数据时,一般不会遇到问题,但如果是用于网络操作,就经常会遇到一些麻烦。 这是因为网络通讯往往是间断性的,一串字节往往分几批进行发送。 例如对方发来字节长度100的数据,本地程序调用available()方法有时得到0,有时得到50,有时能得到100,大多数情况下是100。这可能是对方还没有响应,也可能是对方已经响应了,但是数据还没有送达本地。也

让~学习~成为一种习惯(橡 皮 人の技术博客) 1244

开源滑翔伞升降速度表:基于STM32与传感器融合的DIY飞行仪表

传感器融合是现代嵌入式系统与物联网设备中的核心技术,它通过整合多个传感器的数据,利用滤波与估计算法,获得比单一传感器更精确、更可靠的环境感知能力。其技术价值在于提升系统的鲁棒性、精度和上下文理解能力,广泛应用于无人机导航、可穿戴设备、工业监测及智能驾驶等领域。本文聚焦于一个具体的工程实践案例——开源多功能滑翔伞升降速度表(Open-Vario),该项目巧妙地运用了**卡尔曼滤波器**进行气压与GNSS数据的融合,以精确计算升降率,并基于**FreeRTOS**实时操作系统构建了一个稳定、可扩展的嵌入式平台,

weixin_33657398的博客 177

保姆级教程:用CellOracle 0.10.13从单细胞数据构建基因调控网络(附完整代码)

本文提供了一份详细的CellOracle 0.10.13使用指南,帮助用户从单细胞数据构建基因调控网络。通过Python接口,即使是生物信息学新手也能快速掌握数据准备、KNN插补、GRN计算及可视化等关键步骤。文章包含完整代码和实用技巧,助力单细胞转录组数据分析。

weixin_42563415的博客 725

inputStream.available()方法获取文件字节大小不对的问题

背景介绍:项目中有一个创建合同数据的接口,里面包含了上游系统的文件的url,系统中用URL进行请求文件地址。 代码如下: URL url = new URL(urlAddress); URLConnection uc = url.openConnection(); if (BooleanUtils.isTrue(isNeedHeaders)) { setURLHeaderInfo(uc); } map.put("inputStream", uc.getInputStream()); map.p

weixin_42590506的博客 6690

EtherCAT应用层协议选型指南:CoE、SoE、EoE、FoE、AoE到底怎么选?看完这篇就懂了

本文深入解析EtherCAT应用层协议(CoE、SoE、EoE、FoE、AoE)的选型策略,从实时性、数据吞吐量和功能完整性三大核心指标出发,提供工业场景下的实战决策框架。通过技术特性对比、混合协议架构设计和常见故障规避指南,帮助工程师优化自动化设备通信性能。

weixin_28718793的博客 494

关于 InputStream 类的 available() 方法

API 对 available() 方法说明: /** * 返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。 * 下一个调用可能是同个线程,也可能是另一个线程。 * 一次读取或跳过此估计数个字节不会受阻塞,但读取或跳过的字节数可能小于该数。 */ public int available() throws IOException 要一次读取多个字节时,经常用到 ...

_夜渐凉 2604

多模态论文笔记——CogVLM和CogVLM2

本文详细介绍LoRA版本的多模态模型——CogVLM和CogVLM2。在SD3中使用其作为captioner基准模型的原因和优势。

haopinglianlian的博客 2205

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

还在用InputStream的available()方法获取流的字节数吗?那你可要小心了!

奇怪的事情就发生了,上传的pdf文件下载下来打不开,提示“文件已损坏”。然后按照上面的方式试了一个world文件,结果还是打不开。完犊子了,这代码看着也没问题啊,奇了怪了。因为项目一直就用上面代码的方式去上传文件的啊,要是有问题肯定早就有问题了啊,这个排除掉。因为项目需求,需要从一个url获取文件流然后保存到minio文件服务器中。你说没有获取到流也不对啊,因为确实是上传了一个文件,只是打不开罢了。就去看两个文件的大小,确实是这样,只上传了一部分上去。所以,最后将问题定位到获取到的流肯定没有上传完整。

abzz的博客 951

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

socket InputStream available()lock的问题

在socket InputStream读取数据的问题记录一文中介绍通过input.available()检测是否有可读的字节,上线之后发现服务器load过高,通过jstack发现大量线程都lock在在SocketInputStream.available()上,见截图:   之前以为input.available()会很耗时,通过打点发现原来是调用input.available()过于频繁...

SAN_YUN的专栏 607

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

JAVACPU占用过高、内存泄漏问题排查

📢📢📢📣📣📣哈喽!大家好,我是「奇点」,江湖人称 singularity。刚工作几年,想和大家一同进步🤝🤝一位上进心十足的【Java ToB端大厂领域博主】!😜😜😜喜欢java和python,平时比较懒,能用程序解决的坚决不手动解决😜😜😜✨ 如果有对【java】感兴趣的【小可爱】,欢迎关注我❤️❤️❤️版权声明:本文为优快云博主「HiSiri666666」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

奇点 724

为什么使用HttpUrlConnection时候,用available方法不准确

关于inputStream对象中的available()官方文档是这样给出解释的 inputstream.available()方法返回的值是该inputstream在不被阻塞的情况下一次可以读取到的数据长度。如果数据还没有传输过来,那么这个inputstream势必会被阻塞,从而导致inputstream.available返回0。而对inputstream.read(byte[] byt

yclfdn2004的专栏 1375

Java写一个死循环打满CPU和内存

有一个测试需求,在电脑的CPU和内存达到90%以上的时候去测试一个应用程序是否可以正常使用。所以写一个死循环去把CPU和内存打满。把代码分享给大家,直接拿去用就行了。

weixin_40100234的博客 5225

一文解析!Java进程CPU100%打满

3.终端上使用 printf "%x\n" 命令(tid指线程的id号)将以上10进制的线程号转换为16进制。top 资源消耗分析, shift + p 根据CPU消耗排序,shift + m 根据内存消耗排序。2.使用 top -Hp 命令(为Java进程的id号)查看该Java进程内所有线程的资源占用情况。线程资源消耗分析, shift + p 根据CPU消耗排序,shift + m 根据内存消耗排序。注: 业务上这里日志收集管理是持续检测日志目录,进行日志收集,包装日志收集的实时性和准确性。

bjmsb79的博客 544

记录排查一次CPU高的记录

当用top命令查看时,忘记截图了这个值是100多

每天一点点 345

inputstream的avaliable数据读取不全的坑

关于inputstream的avaliable数据读取不全的坑

ZZJUUID的博客 862

java网络编程中inputStream.available()为0问题

网络流与文件流不同的关键就在于是否“受阻”二字,网络socket流在读取时如果没有内容read()方法是会受阻的,所以从socket初始化的输入流的available也是为零的,所以要。但文件读取时read()一般是不会受阻的,因为文件流的可用字节数 available = file.length(),而文件的内容长度在创建File对象时就已知了。所以调用网络流(socket)的available()方法前,一定记得要先调用read()方法,这样才能避免获取为0的不正确情况。

console的博客 1623

关于inputStream.available()方法获取下载文件的总大小

     如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调用这个函数是在下载文件或者对文件进行其他处理时获取文件的总大小。     以前在我们初学File和inputStream和outputStream时,有需要将文件从一个文件夹复制到另一个文件夹中,这时候我们用的就是inputStream.available()来获取文件的总大小,而且...

hfgerr的专栏 2313

关于网络IO流InputStream.available()相关注意事项

遇到的问题 笔者在进行开发时,从网络中获取对应文件时,需要知道inputStream的大小,经过搜索引擎查询之后得知available可以解决该问题。结果在项目运行时候经常出现数据为0。 原因 在解释这个问题之前,我们都必须知道available返回值,根据api的提示是avaliable用于返回非阻塞情况下,一次性可读的字节数。而SocketInputStream是阻塞的,available的数字每次取决于网络状况。 我们都知道网络是不可靠的,这就导致了有时候获取的是0(双方tcp建立通信,发送方才发送了

禅与计算机程序设计的艺术 1079
下一篇: 默哀日网站置灰,支持IE浏览器&h5
Marvin Liuxz
博客等级 码龄14年 1粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值