簡體   English   中英

使用Runnable和ScheduledExecutorService的內存泄漏

[英]Memory leak with Runnable and ScheduledExecutorService

我正在制作此狀態/菜單欄應用程序,該應用程序在Mac OS X的狀態欄中顯示當前正在播放的歌曲。要從Spotify獲得播放器狀態,我必須創建並執行AppleScript並從中獲取輸出。 然后使用來自Graphics2D的drawString()繪制結果,將其設置到BufferedImage上,然后將其設置為任務欄圖標。

整個代碼是4個類,易於理解,可在此處找到: https : //github.com/ZinoKader/Menify

現在到問題上

我的小跑似乎像以前從未見過的那樣吞噬了記憶。 該應用程序每隔一秒鍾就會使用2-3MB以上的RAM,如果我不這樣做的話,則達到了千兆字節。 到目前為止,我嘗試過的工作是刷新並處理所有圖像和Graphics2D資源,刷新並關閉每個輸入流,輸出流,並銷毀我在AppleScripthHelper中創建的Process對象。

即使是這樣的事情,僅調用靜態方法即可真正快速地堆積RAM。

final Runnable refreshPlayingText = () -> {
    AppleScriptHelper.evalAppleScript(ScriptConstants.SPOTIFY_META_DATA_SCRIPT);
}

//update every 50ms
mainExecutor.scheduleAtFixedRate(refreshPlayingText, 0, 50, TimeUnit.MILLISECONDS);

和AppleScriptHelper

class AppleScriptHelper {

private static final int EOF = -1;

static String evalAppleScript(String code) {

    String[] args = { "osascript", "-e", code };

    try {
        Process process = Runtime.getRuntime().exec(args);
        process.waitFor();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] bigByteArray = new byte[4096];

        InputStream is = process.getInputStream();
        copyLargeStream(is, baos, bigByteArray); //write to outputstream

        String result = baos.toString().trim();

        is.close();
        baos.flush();
        baos.close();
        process.destroyForcibly();

        return result;

    } catch (IOException | InterruptedException e) {
        Log.debug(e);
        return null;
    }
}

private static void copyLargeStream(InputStream input, OutputStream output, byte[] buffer) throws IOException {
    int n;
    while (EOF != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
    }
    input.close();
    output.close();
  }

}

所以問題是,什么消耗了所有的RAM? 為什么貌似什么也沒有垃圾收集?

您面臨的不是內存泄漏!

根據Java™進程和線程教程( https://docs.oracle.com/javase/tutorial/essential/concurrency/procthread.html ),

流程通常具有一套完整的私有基本運行時資源; 特別是,每個進程都有自己的存儲空間。

您每50毫秒創建一個新進程,這很可能會浪費您的可用內存。

創建太多進程將導致thrashing並且您會注意到CPU性能下降。 根據流程的工作方式,最有可能一種更有效的方式來實現您的目標,而無需每秒創建20個流程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM