【发布时间】:2012-11-01 09:41:02
【问题描述】:
我正在努力从现有 Java 代码库中删除所有系统调用。我们在商业提供的闭源 JVM 中运行我们的应用程序。当 JVM 通过 getRuntime.exec() 进行系统调用时,java 调用整个 JVM 进程分叉,这会导致严重的性能损失。我们在 linux 平台上运行,但理想情况下尽量保持可移植性。
我在替换我们当前通过 getRuntime.exec() 方法使用的 sync() 调用时遇到了问题。我知道有thissync() 方法和flush()。基于this post,我希望与所有打开的文件流进行同步和刷新。
我的问题是我不直接知道那里有哪些文件流和描述符。我认为解决这个问题的一种方法是检查 /proc/(jvm 进程号)/fd 文件夹,但我找不到使用纯 java 可靠地获取 JVM 进程号的好方法。我认为我可能能够获取某个类(FileDescriptor 类)的所有对象,但从我正在阅读的内容来看,这也是不可行的。
有人对如何在纯 java 中复制 *nix sync() 调用有建议吗?
【问题讨论】:
-
不会是fork造成性能问题,是文件同步操作。如果你以另一种方式做到这一点,你仍然会遇到同样的问题。
-
我也建议以下链接,它来自 android 开发人员,但由于我们正在谈论的是 Linux / Java 实现 - 它包含相关信息。 android-developers.blogspot.se/2010/12/saving-data-safely.html
-
@auselen - 抱歉,我的原始帖子在这方面并不完全清楚。问题与这样一个事实有关,即在应用程序启动时,我们在假设整个进程可能被分叉的情况下保留可用内存。这实际上将我们的可用内存减少了一半,从而影响了整体性能。
-
@eharik - 你根本不需要这样做处理
System.exec()。 JVM 将使用“vfork”而不是“fork”,并且“vfork”系统调用后跟“exec”系统调用执行最少的复制。 -
@StephenC - 这是真的吗?在这个问题上似乎有一些conflictinginformation。在我们使用系统调用的 JVM 实现中,请尝试分配与父进程相同的内存量。我刚刚运行了一个简单的测试,我将超过 50% 的系统内存分配给了 java 进程并运行了 system.exec() 并且应用程序崩溃了。
标签: java system-calls