title: Java does not free memory
body: <p>I have a daemon program which reads the content of a file, then compress it and write it into smaller .tar.gz files.</p>
  
  <p>For some reason, Java keeps on allocating memory, even after I have freed (or I think I have) all used memory. What is wrong with my code/reasoning?</p>
  
  <pre><code>FileOutputStream fos    = null;
  GZIPOutputStream gzipos = null;
  OutputStreamWriter osw  = null;
  
  BufferedWriter bw = null;
  while (true) {
      if (f.length() != 0) {
          if (outputfile == null) {
              outputfile = outputfileroot + "_" + outputPart + ".tar.gz";
  
              fos = new FileOutputStream(outputfile);
              gzipos  = new GZIPOutputStream(fos);
              osw = new OutputStreamWriter(gzipos);
              bw  = new BufferedWriter(osw);
          }
          else if (new File(outputfile).length() &gt; maxLengthOutputFile) {
              bw.flush();
              osw.flush();
              gzipos.flush();
              fos.flush();
              bw.close();
              osw.close();
              gzipos.close();
              fos.close();
  
              bw  = null;
              osw = null;
              gzipos  = null;
              fos = null;
  
              System.gc();
  
              System.out.println("Finished writing " + outputfileroot + "_" + outputPart + ".tar.gz");
  
              outputfile = outputfileroot + "_" + ++outputPart + ".tar.gz";
              fos     = new FileOutputStream(outputfile);
              gzipos  = new GZIPOutputStream(fos);
              osw     = new OutputStreamWriter(gzipos);
              bw      = new BufferedWriter(osw);
          }
  
          /**
           * Read the entire file
           */
          BufferedReader br = new BufferedReader(new FileReader(f));
          String line;
          while ((line = br.readLine()) != null) {
              // will send the content to another thread, so I need to read it line by line
              bw.write(line + "\r\n");
          }
          br.close();
          br = null;
          bw.flush();
  
          /**
           * Empty it
           */
          FileWriter fw = new FileWriter(f);
          fw.write("");
          fw.flush();
          fw.close();
          fw = null;
      }
  
      Thread.sleep(1000);
  }
  </code></pre>