繁体   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