2011-08-25 126 views
1

在一個網絡項目中,我有多個對象,每個對象都有一個消息隊列(鏈接列表)。每個對象也有一些客戶端,每個客戶端都有一個指向隊列中節點的指針。當一個客戶端收到它的指針所指向的消息時,它的指針將轉到隊列中的下一條消息。現在,當所有的客戶收到一條消息時,我希望這條消息被釋放,所以它不佔用內存。我是通過讓一個單獨的線程遍歷對象並刪除不需要的消息來充當GC的,但是有沒有更好的方法來做到這一點?多鏈接隊列

謝謝。

+0

爲什麼你需要一個單獨的線程?除非您的代碼已經是多線程的,否則您已經介紹了必須使代碼線程安全的複雜性。爲什麼每次發送後您的清理代碼都不運行? – selbie

+0

我不希望它影響性能。但引用計數的想法很好。 – slartibartfast

+0

你爲什麼懷疑它會影響性能?你用測量工具測量過它嗎?性能問題很少出現在你認爲它們的地方。 – selbie

回答

3

您可能可以使用引用計數來處理此問題。假設所有指向隊列元素的指針都來自外部(並且從不在隊列元素之間),則可以在隊列單元中存儲指向它的指針數量。每當你添加一個新的指針,你增加這個引用計數,並且每當程序的一部分完成使用單元格時,它就會降低引用計數,當它達到零時釋放它。這樣,只要有一個指向單元的突出指針,它就不會被釋放,並且一旦最後一個對隊列單元的引用中斷,它就會被回收。你不需要一個單獨的線程來做到這一點。

+0

你擊敗了我的答案。我會修改這個想法「每個客戶保持一條消息隊列的refcounted消息」。 – selbie

1

消息包含訂閱者列表。

每當用戶打開該消息時,用戶數減1。所以,你有一個線程尋找訂閱人數= 0的消息。

這是一個壞主意。

您應該創建一個對象刪除隊列。每次用戶打開一條消息時,它都會檢查用戶數量。如果爲零,則消息訂戶本身將消息提交給刪除隊列。現在GC線程只需要監視刪除隊列。

爲什麼還要打一個櫃檯呢。消息訂戶列表是一個鏈接的令牌列表。每個訂戶都與列表中的一個標記關聯。令牌告訴用戶有一條消息。

如果消息隊列在網絡上運行,則每個訂戶都會生成一個令牌,並且該令牌會鏈接到循環列表中。對於列表中的每個令牌,生成對應的令牌以發送給訂戶。當訂閱者請求消息檢索時,它將其認證令牌提交給消息隊列管理器。消息隊列管理授權令牌並允許訂閱者訪問消息,然後將令牌從列表中解除鏈接。不管它是網絡消息隊列還是本地系統隊列,當最後一個令牌被解除鏈接時(這是一個循環列表 - 你將知道它是最後一個令牌),消息被提交給刪除隊列。