title: Using HashMap.keySet as a dirty copy
body: <p>I have a requirement where I have to use a hashMap where values can change dynamically and keys can get only inserted not deleted or updated. However Keys will be read many times and values may be updated many times. </p>
  
  <p>For latency issues, I haven't made entire HashMap as ConcurrentHashMap in which case while writing keys I will have issues. I am fine with compromising slight data accuracy with keys. So I decided to keep my own dirty copy of keys. A code snippet like below.</p>
  
  <pre><code>package com.test.collections;
  
  import java.util.HashMap;
  import java.util.Map;
  import java.util.Set;
  import java.util.TreeSet;
  import java.util.concurrent.ConcurrentHashMap;
  
  public class CheckKeySet {
  
      private static Map&lt;String, ConcurrentHashMap&lt;String, String&gt;&gt; testMap = new HashMap&lt;String, ConcurrentHashMap&lt;String, String&gt;&gt;();
  
      public static void main(String[] args) {
          CheckKeySet trial = new CheckKeySet();
          try {
              trial.doIt();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }
  
      private void doIt() throws InterruptedException {
          Thread accessThread1 = new AccessKeySet("Access1");
          Thread writeThread = new WriteValueSet();
          Thread accessThread2 = new AccessKeySet("Access2");
          Thread accessThread3 = new AccessKeySet("Access3");
  
          writeThread.start();
          Thread.sleep(1000);
          accessThread1.start();
          Thread.sleep(2000);
          accessThread2.start();
          Thread.sleep(4000);
          accessThread3.start();
      }
  
      private Set&lt;String&gt; getKeySet() {
          return new TreeSet&lt;String&gt;(testMap.keySet());
      }
  
      class AccessKeySet extends Thread {
  
          public AccessKeySet(String string) {
              super(string);
          }
  
          @Override
          public void run() {
              Set&lt;String&gt; keySet = getKeySet();
              System.out.println("###############Trying to print########## " + getName() + " keySet size " + keySet.size());
              for (String s : keySet) {
                  System.out.println(s);
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
  
      class WriteValueSet extends Thread {
  
          @Override
          public void run() {
              int i = 1;
              for (i = 1; i &lt; 10000; i++) {
                  testMap.put("Check-" + i, new ConcurrentHashMap&lt;String, String&gt;());
                  System.out.println("Inserted " + i);
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>My question,  I am creating new Set Object in above implementation with the HashMap.keySet() as base value. HashMap.keySet() will live forever in my code. Will this impact the GC of dirty set objects that I am creating in getKeySet() ? I want this new set object to be cced whenever its holding object becomes eligible for gc. It should not be stopped from getting gced because hashMap.keySet is alive</p>