单例模式引发的内存泄漏:_资源泄漏:救援的命令模式
單例模式引發的內存泄漏:
多年來, 使用Plumbr進行性能監控時,我遇到了數百個資源泄漏引起的性能問題。 在這篇文章中,我想描述一種最簡單的方法來清理資源并避免該問題。
首先,我以電影播放器??應用程序為例來描述問題。 這種應用程序的主要功能自然是在播放電影本身。 按照當今的習慣,我們不想將整個電影收藏存儲在用于播放電影的設備上。 相反,我們將電影下載到本地臨時文件中,然后播放并刪除該文件以釋放下一個電影的空間。 這種工作流程的幼稚實現如下所示:
public class MoviePlayer {private final Catalog catalog = new Catalog();public void play(String movieName, String screen) {Movie movie = catalog.find(movieName);try {movie.fetch();movie.play(screen);} finally {movie.release();}} }class Catalog {Movie find(String name) {return new Movie(name);} }如您所見, MoviePlayer類是Catalog類的客戶端,必須照顧電影播放的整個生命周期。 查找,下載,播放和刪除文件均屬于MoviePlayer類的實現。
這是第一個問題:如果至少一個這樣的客戶端是由一些粗心的開發人員編寫的,他們忘記調用movie.release()方法,那么下載的文件將保留在本地磁盤上。 因此,您播放的每部電影都將添加一個文件,并且設備上的磁盤空間最終將被耗盡。
引入其他功能后,就會暴露出這種“萬事通”代碼的第二個問題。 例如,假設您需要增加記錄實際電影播放時間的可能性。
當前唯一的方法是更改MoviePlayer類。 如果Catalog類有其他客戶,則每個客戶都需要引入更改。 結果, MoviePlayer的每個附加功能都變得越來越大,處理越來越多的獨立問題。 結果,代碼最終將難以理解和更改。
考慮到MoviePlayer應該主要只是處理電影的播放,所以聽起來確實有太多麻煩。 的確,讓我們嘗試將所有這些混亂的內容從MoviePlayer中移出,以確保我們擁有一個負責任的班級。 擁有20年歷史的命令設計模式最適合手頭的任務。
減輕痛苦:救援的命令模式
該方法背后的基本思想是首先抽象出因使用案例而異的操作,以使其與算法中更穩定的部分區分開。 在我們的情況下,這可能涉及電影播放或使用不同的視頻編解碼器進行重新編碼。 因此,包括“查找電影下載-執行某些操作-刪除本地文件”的無聊步驟的樣板將與特定用例隔離。 在我們的示例中,我們可以使用以下簡單的界面進行操作:
上面的更改包括引入一種帶有MovieAction類型的附加參數的新方法。 在此方法中,將執行整個算法:
- 電影已找到。
- 電影已下載。
- 傳遞給該方法的動作或命令在影片上執行。 現在,特定操作是隨用例而變化的唯一可變部分。
- 最后,釋放電影的文件句柄并執行對臨時文件的清理。
現在,如果需要以任何方式更改算法,我們將只在一個地方進行操作,而不會影響仍僅關注其特定動作(例如電影播放或編碼)的任何客戶端。 我們的MoviePlayer示例現在很簡單:
class Catalog {private Movie find(String name) {return new Movie(name);}void withMovie(String movieName, MovieCommand action) {Movie movie = find(movieName);try {movie.fetch();action.execute(movie);} finally {movie.release();}} }該技術非常強大且廣泛。 如果您尚未意識到此用途,請考慮對關系數據庫的JDBC訪問。 所有與獲取數據庫連接,準備語句,獲取結果集以及關閉資源有關的樣板文件,特別是在Spring Templating進行救援之前,都是噩夢般的處理順序。
同樣,可以通過使用命令模式,從不必要的樣板中清除代碼并大大簡化代碼庫,在自定義代碼庫中實現不同方面,例如安全檢查或緩存。
翻譯自: https://www.javacodegeeks.com/2016/09/resource-leakages-command-pattern-rescue.html
單例模式引發的內存泄漏:
總結
以上是生活随笔為你收集整理的单例模式引发的内存泄漏:_资源泄漏:救援的命令模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 别人在局域网看不到自己的电脑(局域网内别
- 下一篇: neo4j 两个点创建关系_Neo4j: