2016-12-03 47 views
1

我已經看到在Go中使用切片的FIFO隊列的一些實現。當項目退出隊列時,可以釋放內存而不重新分配底層數組?如果這沒有發生,在我看來,隊列會泄漏大量的內存。這就是我的意思是:在Go中使用切片的隊列實現

type queue 
{ 
    []int 
    int head 
} 

func (q *queue) enqueue(val int) { 
    q = append(q, val) 
} 

func (q *queue) dequeue() int { 
    return (*q)[q.head++] 
} 

調用入隊/出隊一堆次後,數組的underying切片低指標不再可用,但我不知道他們是如何既可以釋放。有人能指出我的適當的隊列實現不使用指針,並且不會像這樣泄漏內存或者有性能問題嗎?或者,如何這可能工作的說明也將不勝感激。

謝謝 普拉門

+0

首先,如果u想併發你需要在這些方法中,已經開始嗅到互斥鎖。我使用Channels來處理隊列,因爲通道基本上只是堆棧副本。 GC在使用後會清理它們。 – eduncan911

+0

對線程安全不感興趣,只是對這個問題的內存管理。使用渠道來實現隊列是我讀過的一個壞主意,因爲它們與常規調度密切相關,可能會掛起整個程序。在最好的情況下,他們效率低下。這是我讀的這本書:https://www.amazon.com/Programming-Language-Addison-Wesley-Professional-Computing/dp/0134190440 –

+0

上面的代碼不是一個實現,只是爲了說明我的問題 –

回答

1

您可以使用一個循環緩衝區。從wikipedia

循環緩衝器,循環隊列,環狀緩衝器或環形緩衝器是使用一個單一的,固定大小的緩衝器,如同其在連接端至端的數據結構。這種結構很容易緩衝數據流。

...

循環緩衝使得對於具有固定的最大尺寸的隊列中的良好實施戰略。如果隊列採用最大尺寸,那麼循環緩衝區是一個完全理想的實現;所有隊列操作都是恆定時間。但是,擴展循環緩衝區需要移位內存,這相對昂貴。對於任意擴展隊列,鏈接列表方法可能是首選。

這是一個實現這個的包:https://github.com/eapache/queue

根據使用情況,通道也是實現隊列的好方法。它阻止,但使用選擇一個默認的你能避免這種行爲:

select { 
case msg := <-queue: 
default: 
}