2016-08-10 4 views
0

私は基本的に1/60秒ごとに更新されるJavaでゲームを開発しています。このような更新の間に、多くのデータが作成され、渡され、次に参照されずに残され、このデータをDTOと呼ぶことができます。私の理解では、JVMとOSはこのデータをプログラムのヒープに格納します。 JAVA GCが実行されるまでヒープが構築されます。これは、参照されていないすべてのデータを空きとしてマークし、再利用できる状態にします。一時的なヒープを作成して使用する

今、私はそれを見て、これは不必要であり、時々遅れがちです。私が問題を解決したいのは、一時的なヒープとして使用するメモリの割り当てられたチャンクを持つことです。このヒープは、更新間隔中に作成して渡すすべての一時的なものを保存するために使用されます。更新が終わったら、分析は必要ありませんが、チャンク全体がフリーであり、更新後に同じヒープスペースアップデートを再利用するという単純なことができます。テール再帰的スタックフレームのようなもの。

もう1つの解決策は、変更可能なDTOオブジェクトのみを使用し、それらの束を割り当てて再利用することですが、私は可能な限り不変なものを作る利点を利用したいと思います。

は、これは私がコードで何を意味するかを説明するための努力です:

void start(){ 
    Data data = System.allocateDatainMb(500); //allocate 500Mb of virtual memory 
    MagicHeap() mh = System.createAMagicHeap(data); //make a heap of it 
    mh.use(); //set all constructors to allocate on this heap 

    while(true){ 
     update(); 
     mh.clear(); 
    } 
} 

void update(){ 
    TmpData dto = Gamesystem.createALargePieceOfTemporaryData(); 
    someClass.doUpdateStuff(dto); 
} 

私はJavaはメモリを管理する方法とあまり慣れていないんだけど、私はあなたが私の意味を取得願っています。

ある程度可能ですか?

+0

いいえ。 Javaはこれらの技法に適した言語ではありません。 C++に切り替えるか、オブジェクトを再利用してください。 – RealSkeptic

+0

なぜこれが問題だと思うのですか?あなたは実際にGCがあなたのプログラムを遅く停止することに気づいたことがありますか?そうでなければ理由がないと心配しているかもしれません。 – puhlen

+0

私は特に心配していませんし、本当の問題もありません。しかし、GCは目立つが、私は主に好奇心から尋ねた。 – Jake

答えて

0

私は何かが間違っているかもしれませんが、Javaのメモリ管理を妨げるため、Javaでこれを行うことはできません。結局のところ、Javaはユーザーを低レベルのメモリ管理ルーチンから保護することを目的としています。

このように、私はあなたが言及したDTOプールのアプローチに行くことをお勧めします。これを改善する1つの方法は、ミュータル(例:セッターやその他の変異方法)を隠し、ファクトリメソッドなどにアクセスできるようにすることです(パッケージのプライベートな可視性を使用するなど)。その後、一見不変なインスタンスを作成/再利用し、プールを管理するファクトリを持ちます。一時的な「オーバーフロー」を処理することもできます。つまり、プールが実際に提供するものよりも多くのDTOインスタンスが必要な場合です。

しかし、慎重に考えれば、短命であると思われる多くのオブジェクトが、正しく使用されると実際にはより長いライフサイクルになることがわかります。おそらく次のフレームでは必要ない計算(ベクトル/行列演算など)の中間結果ですが、作成した直後に破棄することもできますし、場合によっては回避することもできます(たとえば、プリミティブを手動で使用する場合または複数の中間オブジェクトを持つことができます)。

0

あなたがしようとしていることはJVMよりも優れています。これはあなたがしたいことではありません。実際にメモリ割り当てを直接行う必要がある場合、Javaは適切な言語ではありません。

JavaのGCは、多くの短命オブジェクトを処理するために最適化されています。追加した直後にほとんどのものをメモリから解放することができます。ある種のキャッシングシステムを設定すると、パフォーマンスが低下する可能性があります。これらのオブジェクトはメモリから解放できないため、ヒープのスペースが少なくなり、(完全な)GC休止が頻繁になります。これは、キャッシュシステム自体が生成するオーバーヘッドに加えて行われます。

これは、Javaでのメモリの問題を無視する必要はありません。不必要にオブジェクトを作成しないようにする必要があります。さらに重要なのは、必要以上にオブジェクト参照を保持しないようにして、GCでクリーンアップを許可できるようにすることです。あなたのプログラムニーズに合わせてGCをチューニングし、最新のG1 GCを使用していることを確認することも有益でしょう。

パフォーマンスチューニングと同様に、実際に変更のパフォーマンスの違いを測定することが重要です。あなたが思うものがより速くなると思うことの愚かさを経験することは、努力を惜しまず、複雑さを少しでも増やしたり、悪化させたりすることにつながります。パフォーマンスに関する懸念事項をバックアップするための実数があることを確認してください。

関連する問題