这篇文章是纪录了一个bug解决的过程,可是我还是没有可以真正地找出bug的缘由。希望大牛可以详解。

问题的发现

当接触的系统越来越大的时候,对于系统的性能越来越高的时候,找到表面问题的真正原因就慢慢地成为了一个比較麻烦的问题。说实话,一開始我一直不知道是由于Runtime.getRuntime().exec()导致服务处理时间缓慢。发现这个原因倒是花了不少时间。

为了方便,我直接就用java调用python脚本。用python脚本处理做核心的机器学习算法的东西。

而java调用python脚本,我直接就採用了Runtime.getRuntime().exec(),这个方式相似于直接使用了shell来运行。一開始使用的挺好,也没有注意一些细节的问题,慢慢地用着用着,发现有一台机器处理同样地人脸头像比另外一台慢。从经验上考虑过非常多的可能情况,可是都不是问题的真正原因。

但每个误判。我感觉都非常值得反思。

网络问题

由于我使用了内网穿透工具,本身对工具性能也不熟悉。刚開始的时候立马就想到了是不是由于使用了内网穿透工具。导致网速太慢了。由于这个问题我差点儿就无法解决,所以我一想到这个原因,就没有再去想办法攻克了。

后面直接发现直接从訪问的结果仍然是一样的慢。事实上这个地方我应该去验证一下,直接从内网訪问,看一下速度。

这样就行避免误判带来的问题了。

机器配置问题

由于两台机器配置的时候还是存在一点点不同,我后面又想是不是一台机器配置出现故障?检查了半天还是不能确认是不是机器配置不同,安装的内容不同导致出现了问题。由于没什么时间,干脆我又扔一边去了。

某些随机因素

由于一台机器运行高速,另外一台运行缓慢,而出现这样的诡异的问题,非常easy就让人想到是不是代码库由于某些原因,导致了这样的情况。而往往这样的问题就基本是没有办法搞定了。事实上我还是一个新手的时候。我总是怀疑某些问题是由于一些系统错误,随机因素导致的。可是结果往往是自己的错误。由于有了之前的经验,我潜意识就感觉可能是自己哪段代码出现了错误。

之后通过对代码片段打印时间,每一段运行完都打印时间点。最后查看日志发现,就是在调用process.waitfor的时候,python程序已经返回了,可是java程序仍然没有不论什么响应。还是在wait。

这样才发现了这个问题。

然后通过在网上搜索Runtime.getRuntime()运行程序应该注意的事项,找到问题的关键。我使用waitfor,之后再去读取python程序的输出,可是由于输出一直没有被读取。缓冲区满了,程序就被堵塞。

getRuntime().exec

getRuntime().exec会返回一个Process。在jdk文档中有说明,Process的缓冲区是有限的,假设输出的内容太多,程序就会被堵塞掉。

我一開始的程序是像以下这样的:

​    ​try {
​ ​ final Process p = Runtime.getRuntime().exec("python test.py");
​ ​ ​ ​ p.waitFor();
​ ​ BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
​ ​ try {
​ ​ while (br.readLine() != null)
​ ​ ;
​ ​ br.close();
​ ​ } catch (IOException e) {
​ ​ e.printStackTrace();
​ ​ }
​ ​} catch (Exception e) {
​ ​ e.printStackTrace();
​ ​}

这样的结果就是一台机器在waitFor那里被卡住非常长一段时间。然后參考了网上给的原因,将程序改成以下这样:

    try {
final Process p = Runtime.getRuntime().exec("python test.py"); BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
try {
while (br.readLine() != null)
;
br.close();
} catch (IOException e) {
e.printStackTrace();
}
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}

这样程序就不会长时间卡在那里。甚至于去掉p。

waitFor程序也是OK的。由于程序结束后,Stream就被close掉了。网上非常多人是遇到了由于exec运行的程序出现了错误,结果Error信息占满了缓冲区,导致程序被挂起。

原因探究

从网上看的那些信息仅仅能让我推測可能是由于信息打印太多。没有及时读出,导致程序卡住。

可是我心里还是有疑问,为什么一台机器ok。另外一台机器会卡住,过非常长时间才返回呢?这里面详细的细节方面的原因我认为我还是没有找对。事实上我python程序打印的东西也不多的。

另外也有一个可能是python程序运行完后,非常长时间都没有全然返回。

这也是一个推測的原因。

尽管我依照网上的方式临时攻克了问题。但这些原因事实上我认为都不够充分。希望有人可以给出正确的解释。基础真的要牢靠。

Runtime.exec使用错误导致延迟.md的更多相关文章

  1. 【解决】OCI runtime exec failed......executable file not found in $PATH": unknown

    [问题]使用docker exec + sh进入容器时报错 [root@localhost home]# docker exec -it container-test bash OCI runtime ...

  2. Runtime.exec() sucks!!!!

    自己项目中使用到了 Runtime rt = Runtime.getRuntime(); Process p = rt.exec("query session");p.waitFo ...

  3. 执行Runtime.exec()需要注意的陷阱

    作为Java语言的一部分.java.lang包被隐藏的导入到每一个Java程序.这个包的表面陷阱,经常影响到大多数程序员.这个月,我将讨论运行时exec()方法时的潜伏陷阱. 陷阱4:当运行exec( ...

  4. OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip": executable file not found in $PATH: unknown (Docker容器没有ip addr命令:exec ip addr 报错)

    一.报错 1.报错信息1: OCI runtime exec failed: exec failed: container_linux.go:380: starting container proce ...

  5. Java魔法堂:找外援的利器——Runtime.exec详解

    一.前言 Java虽然五脏俱全但总有软肋,譬如获取CPU等硬件信息,当然我们可以通过JNI调用C/C++来获取,但对于对C/C++和Windows API不熟的码农是一系列复杂的学习和踩坑过程.那能不 ...

  6. Java运行系统命令并获取值(Process java.lang.Runtime.exec(String[] cmdarray, String[] envp, File dir)

    package test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; ...

  7. 权限执行[Android开发常见问题-4] RunTime.exec()如何以root权限执行多条指令?

    每日一贴,今天的内容关键字为权限执行 RunTime.exec()这个接口可以说是给我们开发者供给了一个很好的直观操纵底层操纵系统的机遇,但是这个接口的使用还有很多需要注意的问题.由于要完全的分析这个 ...

  8. Runtime.exec()

    关于RunTime类的介绍: /** * Every Java application has a single instance of class * <code>Runtime< ...

  9. Java Runtime.exec()的使用

    Sun的doc里其实说明还有其他的用法: exec(String[] cmdarray, String[] envp, File dir) Executes the specified command ...

随机推荐

  1. HBase API详解

    一.Java API和HBase数据模型的关系 在Java中,与HBase数据库存储管理相关的类包括HBaseAdmin.HBaseConfiguration.HTable.HTableDescrip ...

  2. html object元素

    知道object是播放音频,但是想了解具体点,百度一下,感觉模模糊糊的,感觉看不大明白,最后找到一个解释比较详细,先从应用,到解释具体属性, 具体网址是: http://www.w3school.co ...

  3. Android Sdk 国内镜像下载地址

    大连东软信息学院镜像服务器地址:- http://mirrors.neusoft.edu.cn 端口:80北京化工大学镜像服务器地址:- IPv4: http://ubuntu.buct.edu.cn ...

  4. 转: Promises与Javascript异步编程

    在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这些年浏览器技术.HTML5以及CSS3等的发展,越来越多的富Web应用出现:在给与我们良好体验的同时,Web开发人员在背后需要处理越来越多 ...

  5. 深度探索QT窗口系统(五篇)

    窗口作为界面编程中最重要的部分,没有窗口就没有界面,是窗口让我们摆脱了DOS时代,按钮是一个窗口,文本框是一个窗口,标签页是一个窗口,...一个窗口可以由多个窗口组成,每天我们都在与窗口打交道,当你打 ...

  6. cocos2dx mac下搭建android开发环境

    1)下载eclipse 地址:http://www.eclipse.org/downloads/ 2)安装adt 打开eclipse,菜单:help->install new software ...

  7. 《Java4Android视频教程》学习笔记(二)

    一:面向对象 1.对象 ①对象的使用方法 对象.变量 对象.方法 ②匿名对象 new A().方法 new A().变量 匿名对象会被分配到对内存中 java内存处理机制会对一定时间内无指针指向的对象 ...

  8. Codeforces 700B Connecting Universities(树形DP)

    [题目链接] http://codeforces.com/problemset/problem/700/B [题目大意] 给出 一棵n个节点的树, 现在在这棵树上选取2*k个点,两两配对,使得其配对的 ...

  9. 吝啬的国度(dfs+vector)

    吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市, ...

  10. 基于mini2440的看门狗(裸机)

    在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生 ...