正好刚才在看别的问题的时候看到了这么一个过程,而这显然不是什么特例而是存在于许多地方的代码。记下来看看。
假如要使用Java来调用系统的某个命令或者程序,则很有可能会用到java.lang.Runtime类的exec系列的方法。这里假设我们要使用的重载是Runtime.exec(String[] cmdarray)。
再假如需要传入命令的参数是从一个长度未知的来源来的,就假设来源是一个Iterable<String>吧。
为了组装出Runtime.exec()方法需要的数组,首先把Iterable<String>的内容都装到一个ArrayList<String>里:
// suppose the source is:
// Iterable<String> src;
ArrayList<String> paramList = new ArrayList<String>();
for (String s : src)
paramList.add(s);
String[] params = paramList.toArray(new String[paramList.size()]);
这一步中,我们至少创建了一个ArrayList和一个String数组。ArrayList在执行add()的时候内部也有可能创建新数组;由于事先不知道长度,所以无法在构造ArrayList的时候预设长度,不过这个就暂时不管了。
接下来,用这个数组来调用exec():
Runtime.getRuntime().exec(params);
然后看看里面发生了些什么事情。
Runtime.exec(String[])调用了Runtime.exec(String[], String[], File);后者的实现是:
public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException {
return new ProcessBuilder(cmdarray)
.environment(envp)
.directory(dir)
.start();
}
OK,那么ProcessBuilder的构造器里又做了什么呢?
public ProcessBuilder(String... command) {
this.command = new ArrayList<String>(command.length);
for (String arg : command)
this.command.add(arg);
}
它把输入进来的String数组转成了一个新创建的ArrayList<String>。
然后在执行到ProcessBuilder.start()的时候呢?
public Process start() throws IOException {
// Must convert to array first -- a malicious user-supplied
// list might try to circumvent the security check.
String[] cmdarray = command.toArray(new String[command.size()]);
for (String arg : cmdarray)
if (arg == null) throw new NullPointerException();
// Throws IndexOutOfBoundsException if command is empty
String prog = cmdarray[0];
SecurityManager security = System.getSecurityManager();
if (security != null)
security.checkExec(prog);
String dir = directory == null ? null : directory.toString();
try {
return ProcessImpl.start(cmdarray,
environment,
dir,
redirectErrorStream);
} catch (IOException e) {
// It's much easier for us to create a high-quality error
// message than the low-level C code which found the problem.
throw new IOException(
"Cannot run program \"" + prog + "\""
+ (dir == null ? "" : " (in directory \"" + dir + "\")")
+ ": " + e.getMessage(),
e);
}
}
注意到这个方法一开始就把先前创建的ArrayList<String>给转换回到了String数组。当然,这个数组又是新创建的。
这个ProcessBuilder.start()方法里又调用了ProcessImpl.start(),其中又再调用了ProcessImpl的构造器;这个构造器中则将刚才来回折腾了多次的参数列拼接为一个大的字符串。
整理一下,刚才经历的过程是:
(来源) ->
ArrayList<String> -> String[] // 我们写的程序
String[] -> ArrayList<String> // ProcessBuilder的构造器
ArrayList<String> -> String[] // ProcessBuilder.start()
String[] -> StringBuilder -> String // ProcessImpl的相关代码
天啊,真是折腾。从现有的JVM的实现看,寿命非常短的对象在垃圾收集时的开销并不很大,创建对象的开销相对来说有可能更大些。(分配空间非常快,开销很小;创建对象的开销主要来自对象的初始化,这部分是用户代码决定的)。
即便如此,明明可以一口气把一个数组用到底的地方被这么来回倒腾显然对运行效率不会有正面影响。
郁闷的是,这些操作都太“详细”了;为了保持代码的语义的正确性,运行时能够做的优化就受到了限制——除非,对这些可以称得上“pattern”的情况做特殊处理,例如说:
看到这样的模式:
// suppose the source is:
// T[] array1;
ArrayList<T> list = new ArrayList<T>();
for (T t : array1)
list.add(t);
T[] array2 = list.toArray(new T[list.size()]);
// do something with array2 in following code
通过SSA之类的方式确认这些相关变量在中间都没有涉及被别的来源赋值,并且list没有被别的地方使用的话,就去掉整个list的构造和赋值等操作。由于JVM可以积极的将方法调用转换为内联的形式,许多时候方法调用链中原本是不同方法中的局部变量就能变成同一个方法的局部变量,从而允许上述优化的实施。
但通过这种模式识别来做就得预先确定很多有代表性的模式才有用。这显然不算是什么好办法。可是还有什么别的、更通用而又能保证程序语义的正确性的办法呢?Hmm……
分享到:
相关推荐
机器人新闻的迷思:“记者”将被淘汰.pdf
### 破除迷思:SOC中的AI 在当今高度数字化的世界中,网络安全已经成为企业和组织不可忽视的关键领域。随着威胁的不断演变和技术的进步,安全运营中心(SOC)面临着前所未有的挑战。本文旨在深入探讨SOC中引入人工...
破解市场迷思: MIPS - 最适用于设计MCU的处理器.docx
解析自有品牌策略与绩效关系的迷思:层级贝氏回归模式之运用.pdf
人工智能(AI)作为一门划时代的伟大技术,在教育领域的应用和发展,往往会伴随着教育迷思的出现。这些迷思主要源于人们对AI技术的过高期望、缺乏科学认识、以及AI与教育结合的不确定性。文章中提到了几个关键点,...
麦肯锡:破解迷思,探索高质量银保发展新模式(2021).pdf
总的来说,《CEO的四大迷思》提供了一个深入理解领导力和组织建设的视角,强调了在追求商业成功时,不应忽视内部组织的健康和长期发展。它不仅适用于CEO,也对所有级别的管理者都有启发意义,帮助他们理解并克服在...
《教养的迷思》读后感.pdf
美国低通胀迷思与中期展望:高核心通胀将挑战美联储宽松政策
“七式团队迷思”是一个由心理学家欧文·珍尼斯提出的概念。这个概念描述的是一个团队陷入迷思的情况,从而导致团队作出一些劣质的决策。这种现象在团队管理中是非常普遍的,也是团队领导者需要特别注意的问题。 ...
这篇报告的标题“20201111-中银国际-美国低通胀迷思与中期展望:高核心通胀将挑战美联储宽松政策”揭示了报告的核心内容,主要讨论了2020年美国的低通胀现象以及对未来中期经济前景的展望。报告特别指出,高核心通胀...
科技品牌十大迷思
这些模式各自有不同的优势和特点,但在共同点上,银保合作可以为双方带来“双赢”的局面,从而实现价值的最大化。银保渠道的成功要素可以概括为五个主要方面,这些要素共同推动银保业务价值的释放,包括共同产品共创...
CEO管理运营之道经典实用课件之二:CEO四大迷思.ppt
在探讨人工智能时代的迷思时,我们不可避免地会接触到两个核心议题:技术恐惧与技术拜物教。这两个概念不仅涉及人工智能技术本身的发展,也与社会、文化和伦理等因素紧密相关。以下将详细阐述这两个概念的内涵、成因...
### 破解青春期的迷思 青春期是一个充满变化与挑战的生命阶段,它不仅对青少年自身,也对周围的成人提出了考验。本文旨在澄清并解答围绕青春期的一些常见误解,帮助青少年及其监护人更好地理解和应对这一时期的种种...
【汽车行业经理人迷思】指的是在汽车行业中,经理人们经常陷入一些思维误区,这些误区可能导致组织效率低下,甚至企业衰败。以下是对这些迷思的详细解析: 1. 局限思考:经理人往往过于专注于自己的职责范围,而...
同时,线上平台也为学生提供了更多展示自己思考和学习成果的机会,这有助于培养学生的自我表达能力和批判性思维。 在教学实践中,教师应不断积累教学经验,优化教学设计,使之更加符合在线教学的特点。教学内容的...