title: Why used heap is always increasing in my MINA application?
body: <p>I have an application which consists of two parts as server and client. </p>
  
  <p>It works like this :</p>
  
  <p>Client connects to the server and sends a string; server receives the string and returns an ArrayList (by converting string) which contains 10000 elements.</p>
  
  <p>I wrote a class (ClientConnector.java) which simulates many clients use one connection to take those 10000 elements from server.</p>
  
  <p>When I run this two programs, server side is ok. However on the client side, used heap is always increasing ! I tried to release the used objects by "null" but the used memory is still getting larger and larger.</p>
  
  <p><a href="http://s10.postimage.org/egf4ugrd5/mem.png" rel="nofollow">http://s10.postimage.org/egf4ugrd5/mem.png</a></p>
  
  <p>My Server Side Codes : 
  Client.java</p>
  
  <p>public class Client {</p>
  
  <pre><code>private static final int PORT = 7571;
  ClientHandler handler = new ClientHandler("hey");
  IoConnector connector;
  boolean available = true;
  
  public synchronized void setAvailable(boolean available) {
      this.available = available;
  }
  
  public synchronized boolean isAvailable() {
      return available;
  }
  
  public void starter() throws InterruptedException {
  
      Thread t = new Thread(new Runnable() {
          @Override
          public void run() {
  
              connector = new NioSocketConnector();
              connector.getSessionConfig().setReadBufferSize(2048);
              TextLineCodecFactory t = new TextLineCodecFactory(Charset.forName("UTF-8"));
              t.setEncoderMaxLineLength(20 * 150000);
              t.setDecoderMaxLineLength(20 * 150000);
              connector.getFilterChain().addLast("logger", new LoggingFilter());
              connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(t));
  
              connector.setHandler(handler);
              ConnectFuture future = connector.connect(new InetSocketAddress("localhost", PORT));
              future.awaitUninterruptibly();
  
              if (!future.isConnected()) {
                  return;
              }
  
              IoSession session = future.getSession();
              session.getConfig().setUseReadOperation(true);
              session.getCloseFuture().awaitUninterruptibly();
  
              connector.dispose();
          }
      });
      t.start();
      Thread.sleep(300);
  }
  
  public void conClose() {
      connector.dispose();
  }
  
  public ClientHandler getHandler() {
      return handler;
  }
  
  public void reqInf() {
      handler.reqInfo();
  }
  
  public static void main(String[] args) {
      try {
          Client c = new Client();
          c.starter();
      } catch (InterruptedException ex) {
          System.out.println("error");
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>ClientHandler.java</p>
  
  <p>public class ClientHandler extends IoHandlerAdapter {</p>
  
  <pre><code>long time;
  private final String values;
  IoSession session;
  
  public ClientHandler(String values) {
      this.values = values;
  }
  
  @Override
  public void sessionOpened(IoSession session) throws InterruptedException {
      this.session = session;
  }
  
  public ArrayList&lt;String&gt; convert(String str) {
      Gson gson = new Gson();
      return gson.fromJson(str, ArrayList.class);
  }
  
  @Override
  public void messageReceived(IoSession session, Object message) throws InterruptedException {
  
      try {
          ArrayList&lt;String&gt; test = convert(message.toString());
          System.out.println("TIME : " + (System.currentTimeMillis() - time) + " strList:" + test.size());
          message = null;
          test = null;
  
      } catch (Exception ex) {
          ex.printStackTrace();
      }
  }
  
  @Override
  public void exceptionCaught(IoSession session, Throwable cause) {
      session.close();
      System.out.println(cause.toString());
  }
  
  @Override
  public void sessionClosed(IoSession session) {
  
      System.out.println("Connection Lost");
  }
  
  public void reqInfo() {
      time = System.currentTimeMillis();
      session.write("test");
  }
  </code></pre>
  
  <p>}</p>
  
  <p><strong>My Server Side :</strong>
  Server.java</p>
  
  <p>public class Server {</p>
  
  <pre><code>private static final int PORT = 7571; //TEST PORT
  IoAcceptor acceptor = new NioSocketAcceptor();
  
  public Server() throws IOException {
      TextLineCodecFactory t = new TextLineCodecFactory(Charset.forName("UTF-8"));
      t.setEncoderMaxLineLength(20*150000);
      t.setDecoderMaxLineLength(20*150000);
      acceptor.getFilterChain().addLast("logger", new LoggingFilter());
      acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(t));
      // acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
  
      Executor executor = new ThreadPoolExecutor(5, 70, 60, TimeUnit.SECONDS, new LinkedBlockingQueue&lt;Runnable&gt;());
  
      acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(executor));
      acceptor.setHandler(new ServerHandler());
      acceptor.getSessionConfig().setReadBufferSize(2048);
      acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 1000);
  
      //timer();
  
      acceptor.bind(new InetSocketAddress(PORT));
      System.out.println("***Mina Server is ready !");
      System.out.println("");
      System.out.println("");
  
  
  }
  
  
  public static void main(String[] args) throws IOException {
      Server m = new Server();
  }
  </code></pre>
  
  <p>}</p>
  
  <p>ServerHandler.java</p>
  
  <p>public class ServerHandler extends IoHandlerAdapter {</p>
  
  <pre><code>private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
  IoSession sessions;
  //Communication communication;
  
  public ServerHandler() throws IOException {
      loader();
      // communication = new Communication(this);
  }
  
  @Override
  public void sessionOpened(IoSession session) {
      // set idle time to 10 seconds
      session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 1000);
      System.out.println("Client Connected !!!");
      //session.setAttribute("Values: ");
      this.sessions = session;
  
  }
  
  public String toGSon(ArrayList&lt;String&gt; list) {
      Gson gson = new Gson();
      String str = gson.toJson(list);
      return str;
  }
  ArrayList&lt;String&gt; str = new ArrayList&lt;String&gt;();
  
  public void loader() {
      for (int i = 0; i &lt; 10000; i++) {
          str.add("test" + i);
      }
  }
  
  @Override
  public void messageReceived(IoSession session, Object message) throws InterruptedException {
  
      long time = System.currentTimeMillis();
      session.write(toGSon(str));
      System.out.println("TIME : " + (System.currentTimeMillis() - time));
  
  }
  
  @Override
  public void sessionIdle(IoSession session, IdleStatus status) {
      System.out.println("Socket #" + session.getId() + " is disconnecting... (IDLE)");
      session.close();
  }
  
  @Override
  public void exceptionCaught(IoSession session, Throwable cause) {
      System.out.println("------------&gt;" + cause.toString());
      session.close();
  }
  </code></pre>
  
  <p>}</p>
  
  <p>And my Main Class</p>
  
  <p>public class ClientConnector {</p>
  
  <pre><code>public ClientConnector() throws InterruptedException {
      Client cl = new Client();
      cl.starter();
      while (true) {
  
          cl.reqInf();
          Thread.sleep(100);
      }
  }
  
  public static void main(String[] args) throws InterruptedException {
      ClientConnector cl = new ClientConnector();
  }
  </code></pre>
  
  <p>}</p>