title: Memory leak with Runnable and ScheduledExecutorService
body: <p>I'm making this status/menu bar app which displays the currently playing song in the status bar for Mac OS X. To get the player status from Spotify I have to create and execute an AppleScript and get the output from this. The result is then drawn using drawString() from Graphics2D, which is set onto a BufferedImage which is then set as the tray icon.</p>
  
  <p>The whole code is 4 classes and easy to follow, available here: <a href="https://github.com/ZinoKader/Menify" rel="nofollow noreferrer">https://github.com/ZinoKader/Menify</a></p>
  
  <p><strong>Now onto the problem</strong></p>
  
  <p>My runnable seems to eat up memory like nothing I've seen before. Every second the application uses 2-3MB more RAM, and reaches for gigabytes if I leave it be. What I have tried so far is to flush and dispose of all my images and Graphics2D resources, flush and close every inputstream, outputstream and destroy the Process object I create in AppleScripthHelper.</p>
  
  <p>Even something like this, just calling a static method starts piling up RAM really quickly. </p>
  
  <pre><code>final Runnable refreshPlayingText = () -&gt; {
      AppleScriptHelper.evalAppleScript(ScriptConstants.SPOTIFY_META_DATA_SCRIPT);
  }
  
  //update every 50ms
  mainExecutor.scheduleAtFixedRate(refreshPlayingText, 0, 50, TimeUnit.MILLISECONDS);
  </code></pre>
  
  <p>and AppleScriptHelper</p>
  
  <pre><code>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();
    }
  
  }
  </code></pre>
  
  <p>So the question is, what is eating up all of that RAM? Why is seemingly nothing being garbage collected?</p>