1

信頼できないJavaコードのサンドボックスを作成しようとしています。
私はJavaを使用してサンドボックスを作成しました。サンドボックスは次の目的で必要です。

  1. 信頼できないコードのメモリ使用量を制限します。信頼できないコードが指定された制限を超えるメモリを使用する場合、サンドボックスはプログラムを終了する必要があります。
  2. 信頼できないコードが指定された制限を超えない場合、サンドボックスは使用される「最大メモリピーク」も判別できる必要があります。

ところで、ここでメモリと言ったとき、それはヒープ+非ヒープメモリを意味します。

メモリしきい値を設定し、メモリプールの1つがしきい値を超えた場合に通知を受けることができることがわかりました。しかし、ヒープ+非ヒープメモリの制限を設定したいので、これは私が望んでいたことではありません。

私が現在持っている唯一の解決策は、小さなミリ秒ごとにポーリングし、 MemoryMXBeanからgetHeapMemoryUsage()とgetNonHeapMemoryUsage()を使用してヒープと非ヒープメモリを取得し、制限を超えているかどうかを確認することです。

しかし、私はこの解決策も間違いなく良くないことを知っています(そして欠陥があります)。他にもっと良い解決策はありますか?

4

2 に答える 2

5

単一の JVM には、すべてのスレッド間で共有ヒープがあります。メモリを「サンドボックス化」することはできません。アプリケーションごとにメモリを管理する場合は、別のプロセスを実行する必要があります。

全体のメモリ (ヒープ + 非ヒープ) を制限したい場合は、 JNA経由でシステム関数setrlimit (Linux を実行している場合) を呼び出すか、Java プロセスを実行する前にulimitを呼び出すことができます。

プロセスが使用しているメモリ量を調べるには、ManagementFactory.getOperatingSystemMXBean()から CommittedVirutalMemorySize 属性を取得します(ただし、getter はありません)。

差し迫ったシャットダウンの通知を受け取りたい場合は、setrlimit/ulimit のソフト制限を使用してください。プロセスは、ソフト制限を超えたというシグナルを定期的に受け取ります。ハードリミットを設定してそれを超えると、プロセスは強制終了されます。

編集: メモリ サイズと setrlimit シグナルの取得に関する段落を追加しました。

于 2012-12-14T04:15:13.280 に答える
1

これは深い魔法がなければできないと思います。信頼できないコードのバイトコードを書き直すか、基になる JVM を変更してメモリ使用量を追跡する必要があります。

実験として、信頼できないコードのメモリ割り当て (および命令消費) を制限するために前者 (バイトコードの書き換え) を実装し、-javaagents を使用してロード時に Java クラスのバイトコードを書き換え、チェックを挿入しました。すべてのメモリ割り当ての前に。

これにより、関数を呼び出して、その関数 (およびそれが呼び出すもの) を、たとえば 1024 バイトのメモリ割り当てと 10000 命令に制限し、オーバーシュートした場合にスローして例外を発生させることができます。ちょっとした作業コードは次の場所で入手できます

https://github.com/lihaoyi/6858

tl; 博士: かなり大変です。不可能というわけではありませんが、締め切りが迫っている場合にやろうとすることではありません。本当にうまくいけば、おそらく会議論文を発表できるでしょう。

于 2012-12-30T04:42:47.483 に答える