2

フォークを使用しないJavaRuntime.exec()の代替を見つけようとしています。JVMがメモリの大部分を消費し、そのプロセスでRuntime.execフォークがメモリの問題を引き起こす可能性があるという問題は、コピーオンライトとオーバーコミット(stackoverflowでよく説明されています。JavaRuntime.getRuntime()。execを参照)でも発生する可能性があります。 ()代替)。

別のstackoverflowの投稿で、JNAを使用して解決策が提案されましたが、この解決策についてのコメントはなく、高く評価されていませんでした:Runtime#exec(を呼び出して「java.io.IOException:error = 12、メモリを割り当てることができません」を解決する方法)?

同様に、同様のJNAソリューションがここで提案されました:http ://sanjitmohanty.wordpress.com/2011/12/20/overcoming-runtime-exec-havoc-with-jna/

私の質問は、JNAを使用してシステムコールを行うことでフォークが防止され、フォークが引き起こす可能性のある後続のメモリ割り当ての問題が回避されるかどうかです。これが私が使用しているコードです:

public class TestJNA {
 private interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
    int system(String cmd);
 }
 private static int exec(String command) {
    return CLibrary.INSTANCE.system(command);
 }
 public static void main(String[] args) {
    exec("ls");
 }
4

4 に答える 4

3

いいえ (または同等systemの)を行う必要がありfork、JNAはそれについて何もできません。

JNAを使用して電話をかけることを提案しているsystemのではなく、実際のシステムコールを行うことを提案していると思います。たとえば、そのブログは例としてchmodとを示してchownいます。system('ls')したがって、JNAを使用して呼び出し、呼び出しopendir、およびを実行する代わりに、例を使用しますreaddir(もちろん、実際に呼び出しているものにも同じことが当てはまります)。

必要な機能をラップするためにDLLを作成する必要がある場合があります。

于 2012-05-24T00:24:24.913 に答える
3

おそらくそうではありません。呼び出している実装はsystem()、ほぼ確実fork()にそれ自体を使用しています。Cの実装は次のようになります。

int system(const char *cmd) {
    if (fork() == 0) {
        execl("/bin/sh", "-c", cmd);
        _exit(1);
    }
    int result;
    wait(&result);
    return WEXITSTATUS(result);
}

より実現可能な解決策は、サブプロセスを生み出すことができる小さな外部プロセスへの通信回線(パイプなど)を維持することです。Androidはこのようなことをします。外部プロセスは「接合子」として知られています。

于 2012-05-24T00:26:42.207 に答える
1

fork()なしで「システム」を実行する方法はおそらくありません。

于 2012-05-24T00:24:49.677 に答える
0

それでは、system() はどのように機能するのでしょうか? まだフォークを使用している場合は?このエラー「java.io.IOException:エラー= 12、メモリを割り当てることができません」という問題があり、これで解決しました:

private interface CLibrary extends Library {
            CLibrary INSTANCE = (CLibrary) Native.loadLibrary(("c"), CLibrary.class);
        int system(String cmd);
    }

    private static int exec(String command) {
        return CLibrary.INSTANCE.system(command);
    }
于 2013-12-26T10:04:26.503 に答える