Java でこれを尋ねるのは奇妙な質問だと思いますが、Java の動的メモリ割り当てをいくつかの配置制約に合わせる方法はありますか? たとえば、ページ サイズに合わせてオブジェクトを動的に割り当てることは可能ですか?
これを行う理由は、JNI インターフェイスを介してネイティブ コードから Java オブジェクトにアクセスするためであり、ネイティブ コード ライブラリではオブジェクトを整列させる必要があります。
ありがとう。
Java でこれを尋ねるのは奇妙な質問だと思いますが、Java の動的メモリ割り当てをいくつかの配置制約に合わせる方法はありますか? たとえば、ページ サイズに合わせてオブジェクトを動的に割り当てることは可能ですか?
これを行う理由は、JNI インターフェイスを介してネイティブ コードから Java オブジェクトにアクセスするためであり、ネイティブ コード ライブラリではオブジェクトを整列させる必要があります。
ありがとう。
いいえ、できません。Java のヒープ上のオブジェクトは、ガベージ コレクション中に移動できることに注意してください。いくつかのオプションがあります:
このブログ投稿を参照して、要件もカバーする Java でのダイレクト メモリ アラインメントのより広い議論を参照してください。要約する:
適切なアドレスに到達するまで、割り当てを繰り返さないことをお勧めします。これは、ソフトウェアにとって非常に悪いことです。アドレスを繰り返し取得する予定がある場合、上記のリフレクション メソッドを使用する予定がある場合は、アドレスをキャッシュすることをお勧めします。または、投稿で概説されている方法を使用して Unsafe を使用し、アドレス フィールドの値を取得します。
美しいオプションはないので、醜いオプションを次に示します。
Sun (現在は Oracle) JRE 5.0 または 6.0 を使用している場合は、次を使用できます。
ByteBuffer buffer = ByteBuffer.allocateDirect(pageSize);
Method getAddress = buffer.getClass().getMethod("address");
long address = getAddress.invoke(buffer);
// and now send address to JNI
Java でデータにアクセスするには、bufferを使用します。JNI でアクセスするには、アドレスをポインタにキャストします。どちらも同じデータを表示/変更します。
アドレスはページ境界で整列されているはずですが、それを確実にするために、2 つのページを割り当てることができます (完全に整列されたページに対して十分なスペースがあるはずです)。次に、ページ上のアドレスを揃えて、オフセットを ByteBuffer アクセスに適用します。
任意の VM で機能するバッファー割り当てとネイティブ呼び出しの別のオプションは、JNAs メモリ クラスを使用することです: http://jna.java.net/javadoc/com/sun/jna/Memory.html。com.sunパッケージで怖がらないでください。オープンソースであり、LGPL です。