这篇文章是纪录了一个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程序运行完后,非常长时间都没有全然返回。

这也是一个推測的原因。

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

转载于:https://www.cnblogs.com/bhlsheji/p/5232655.html

Runtime.exec使用错误导致延迟.md相关推荐

  1. java runtime shell_java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现...

    Runtime.getRuntime().exec()执行JVM之外的程序:常见的几种陷阱 前言 日常java开发中,有时需要通过java运行其它应用功程序,比如shell命令等.jdk的Runtim ...

  2. ※※Java调用Runtime.exec()要注意的问题

    ※※Java调用Runtime.exec()要注意的问题 标签:execJavaRuntime 字体:[默认中大] http://it.superkoo.com/#/topic/479/ 最近开发一个 ...

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

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

  4. Runtime.exec 调用OS命令特例

    1. 运行带有重定向的命令. String[] shellCommand = {"/bin/ksh", "-c", "/usr/lib/sendmai ...

  5. [转]Java中Runtime.exec的一些事

    0 预备知识 1 不正确的调用exitValue 2不正确的调用waitFor 3 一种可接受的调用方式 4 调用认为是可执行程序的时候容易发生的错误 5 window执行的良好示例 6 不良好的重定 ...

  6. java中exec命令,使用Java中的Runtime.exec()執行Windows命令

    Runtime.getRuntime().exec()方法主要用於執行外部的程序或命令.Runtime.getRuntime().exec共有六個重載方法 : 其中public Process exe ...

  7. java runtime 返回值_Java Runtime.exec()注意事项 | 学步园

    转载自:http://blog.csdn.net/flying881114/archive/2011/03/23/6272472.aspx 0. Runtime.exec()用来执行外部程序或命令 1 ...

  8. runtime无法执行grep_如何使管道使用Runtime.exec()?

    慕运维8079593 我在Linux中遇到了一个类似的问题,只不过是"ps-ef_grep找进程".至少使用"ls"可以替换与语言无关(尽管速度较慢)的Java ...

  9. Java Runtime.exec()的使用

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

最新文章

  1. java工具集_Java 工具集
  2. Python基础总结(3)
  3. 【Python】编程笔记10
  4. setContentView( )方法
  5. mysql redis 中间件_Docker快速搭建Mysql社区版,Redis,MongoDb、MQ等等中间件。
  6. 切换数据库_如何快速切换到其他数据库实例
  7. mockjs的介绍、基本使用和封装
  8. 车牌识别程序_在线的,离线的车牌识别
  9. Tomcat历史版本下载
  10. CSDN博客代码片黑色背景及代码高亮设置
  11. 在Linux上安装字体
  12. 计算机台式硬件排名价格,台式机电脑主板排名
  13. CentOS8下超详细安装配置kubernetes(K8S)
  14. im即时通讯消息id的设计
  15. VOS客户端动态黑名单功能配置详解
  16. 计算广告(1)---一些概念
  17. 并发编程含义比较广泛,包含多线程编程、多进程编程及分布式程序等 目录 1. “共享内存系统”,消息传递系统”。 1 1.1. 共享模式 多进程 多线程 1 1.2. Actor消息模式 事件驱动 2
  18. ubuntu进去安全模式_win10和Ubuntu双系统,无法开机如何进入win10安全模式
  19. 全球及中国智能医疗产品行业发展态势及投资可行性研究报告2022-2027年
  20. 轻松转换CAJ文件为PDF格式:免费工具和技巧

热门文章

  1. SQL中Convert()函数的使用方法
  2. 虚拟机不能上网以及无法ping通百度的解决方案
  3. mysql key value_【mysql】大量的 key = value 值用什么方式存储?
  4. python pymysql实例_Python使用pymysql模块操作mysql增删改查实例分析
  5. 识别中文_中文场景文字识别大赛官方baseline
  6. 电脑右下,电脑右下图标怎么显示出来怎么办
  7. tomcat websock html5,websocket实战(4) websocket版贪食蛇游戏(tomcat官方自带)
  8. python指定时间执行程序_如何在特定时间执行程序
  9. Windows10下VB6.0开发——利用PictureBox控件实现数据点实时绘图
  10. 用java语言求前50个素数_Java求质数的几种常用算法总结