11

500kを超えるオブジェクトの状態情報を追跡するプロジェクトがあります。プログラムは、これらのオブジェクトについて1秒あたり10kの更新を受け取ります。更新は、新規、更新、または削除の操作で構成されます。

プログラムの一環として、これらのオブジェクトに対して約5分ごとにハウスキーピングを実行する必要があるため、この目的のために、これらのオブジェクトのハウスキーピングを制御できるように、インターフェイスのDelayQueue実装に配置しました。DelayedDelayQueue

  • 新規の場合、オブジェクトはに配置されますDelayQueue

  • 更新されると、オブジェクトはremove()からDelayQueue削除され、更新されてから、更新された情報によって指定された新しい位置に再挿入されます。

  • 削除すると、オブジェクトはremove()から'dになりDelayQueueます。

私が直面している問題はremove()、キューが約45万個のオブジェクトを通過すると、メソッドが非常に長い操作になることです。

プログラムはマルチスレッドであり、1つのスレッドが更新を処理し、もう1つのスレッドがハウスキーピングを処理します。遅延がremove()原因で、厄介なロックパフォーマンスの問題が発生し、最終的には更新スレッドバッファがすべてのヒープスペースを消費します。

を作成することでこれを回避することDelayedWeakReference (extends WeakReference implements Delayed)ができました。これにより、「シャドウ」オブジェクトを正常に期限切れになるまでキューに残すことができます。

これにより、パフォーマンスの問題は解消されますが、メモリ要件が大幅に増加します。DelayedWeakReferenceこれを行うと、実際にキューに入れる必要のあるすべてのオブジェクトに対して約5秒になります。

高速操作DelayQueueを可能にする追加の追跡機能を知っている人はいますか?remove()または、大幅に多くのメモリを消費せずにこれを処理するためのより良い方法の提案はありますか?

4

3 に答える 3

3


これについて考えるのに少し時間がかかりました
が、興味深い質問を数分間読んだ後、私のアイデアは次のとおりです
。A.オブジェクトに何らかのIDがある場合は、それを使用してハッシュし、実際には1つの遅延キューがありません。ただし、N個の遅延キューがあります。
これにより、ロック係数がN減少し ます。これらのN個のキューを保持
する中央データ構造があります。
Nは事前設定され
ているため、システムの起動時にN個すべてのキューを作成できます。

于 2012-11-16T17:00:50.393 に答える
1

「ほぼ5分ごと」にハウスキーピングを実行するだけでよい場合、これはそれを維持するための多くの作業です。

私が行うことは、最後の更新から5分経過しているかどうかを確認するために、毎分(または必要に応じてそれ以下)実行されるタスクを作成することです。このアプローチを使用する場合、維持する追加のコレクションはなく、更新時にデータ構造が変更されることもありません。コンポーネントをスキャンするオーバーヘッドは増加しますが、一定です。更新を実行するオーバーヘッドはわずかになります(最後に更新された時刻でフィールドを設定します)

于 2012-11-16T16:58:38.253 に答える
0

私があなたの問題を正しく理解しているなら、あなたはそれが5分間触れられていなければ、オブジェクトに何かをしたいと思うでしょう。

カスタムリンクリストを作成できます。尻尾は最近触れたものです。ノードの削除は高速です。

簿記スレッドは、1秒ごとにウェイクアップし、5分経過したヘッドを削除するだけです。ただし、1秒の遅延が許容できない場合は、正確な一時停止時間を計算してください

// book keeping thread

void run()

  synchronized(list) 

    while(true)

        if(head==null)
            wait();
        else if(  head.time + 5_min > now )
            wait( head.time + 5_min - now );
        else 
            remove head
            process it


// update thread

void add(node)
  synchronized(list) 
    append node
    if size==1
        notify()  

void remove(node)
  synchronized(list) 
    remove node    
于 2012-11-16T17:52:10.990 に答える