2012-11-16 19 views
9

我有一個項目可以跟蹤超過500k個對象的狀態信息,程序每秒接收10k次關於這些對象的更新,更新包括新的更新或刪除操作。DelayQueue更高的速度remove()?

作爲該計劃的內部管理的一部分,必須對這些對象進行大約每隔五分鐘,爲了這個目的,我把他們安置在一個DelayQueue實現Delayed接口,允許DelayQueue的攔截功能來控制的看家這些對象。

  • 新的時候,對象被放在DelayQueue上。

  • 更新後,對象是中的remove()'d,更新並重新插入到由更新信息指示的新位置。

  • 刪除後,對象是的remove()'d。

我所面臨的問題是,一旦該隊列繞過450K對象remove()方法變成過分長時間操作。

程序是多線程的,一個線程處理更新,另一個線程處理更新。由於remove()延遲,我們得到令人討厭的鎖定性能問題,並且最終更新線程緩衝區佔用了所有堆空間。

我已經設法通過創建一個DelayedWeakReference (extends WeakReference implements Delayed)來解決這個問題,它允許我在隊列中保留「陰影」對象,直到它們正常過期。

這消除了性能問題,但會導致內存需求的顯着增加。這樣做對於實際上需要在隊列中的每個對象都會產生大約5 DelayedWeakReference

有沒有人知道DelayQueue附加追蹤,允許快速remove()操作?或者有沒有更好的方法來處理這個問題,而不消耗更多的內存?

+0

只是好奇...但是這究竟是什麼(除了技術問題之外)? –

+0

它是處理防火牆狀態表內容的引擎,它從防火牆獲取文本輸出並重構內存中的狀態表。這允許您執行大量操作和分析,並且更重要的是定期導出其他格式的信息,導出NetFlow中使用的自上次更新以來的差異。 – CuddlyDragon

回答

2


我花了一些時間來思考這個,
但是讀你的有趣的問題了幾分鐘後,這裏有我的想法:
A.如果你的對象有某種類型的ID,用它來散列,實際上沒有一個延遲隊列,但有N個延遲隊列。
這將減少鎖定因子N.
將有一箇中央數據結構,
持有這些N個隊列。由於N已預配置,因此您可以在系統啓動時創建所有N個隊列。

+0

這是一個我沒有考慮過的有趣的方法,將'DelayQueue'分割。使用模數將對象分配給不同的對象將會很容易,因爲它們都具有唯一的ID。這可能是一種擴展的方法。 – CuddlyDragon

+0

確實,這正是我的意思。如果你能測試這一點,我將不勝感激,如果有幫助,upvote :) –

+0

這是我短期內最好的選擇,並且可能會在短期到中期滿足我的需求。我可能會嘗試爲我自己的需要設計一個更專用的隊列,以提供所需的功能。 - 謝謝! – CuddlyDragon

1

如果你只需要執行管家「大約每隔五分鐘」,這是配發工作來維持。

我會做的是有它運行每分鐘(或更少根據需要),看它是否已自上次更新五分鐘的任務。如果您使用這種方法,則不需要額外收集來維護更新,也不會更改數據結構。掃描組件的開銷增加了,但是不變。執行更新的開銷變得微不足道(設置字段與上次更新時間)

+0

感謝您的建議,我確實考慮定期對「HashMap」進行「全面掃描」,而不是使用「DelayQueue」。然而,我很快意識到,它需要成爲該特定對象的紀念日,即它們並不都具有相同的限制。我會每五分鐘對掃描的性能差異進行一些測試,而不是延遲方法。 – CuddlyDragon

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  
+0

我懷疑的問題是在'DelayQueue'中搜索要刪除的對象,它在內部使用'PriorityQueue',而後者又使用'Object []'來存儲。我不知道LL是否會更快搜索,還是不同的是它可以在不鎖定整個結構的情況下完成? – CuddlyDragon