清单 1. 使用一个全局 Map 将元数据关联到一个对象  public class SocketManager {   private Map<Socket,User> m = new HashMap<Socket,User>();  public void setUser(Socket s, User u) {   m.put(s, u);   }   public User getUser(Socket s) {   return m.get(s);   }   public void removeUser(Socket s) {   m.remove(s);   }  }  SocketManager socketManager;  ...  socketManager.setUser(socket, user);
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
清单 2. 具有基于 Map 的内存泄漏的程序  public class MapLeaker {   public ExecutorService exec = Executors.newFixedThreadPool(5);   public Map<Task, TaskStatus> taskStatus   = Collections.synchronizedMap(new HashMap<Task, TaskStatus>());   private Random random = new Random();  private enum TaskStatus { NOT_STARTED, STARTED, FINISHED };  private class Task implements Runnable {   private int[] numbers = new int[random.nextInt(200)];  public void run() {   int[] temp = new int[random.nextInt(10000)];   taskStatus.put(this, TaskStatus.STARTED);   doSomeWork();   taskStatus.put(this, TaskStatus.FINISHED);   }   }  public Task newTask() {   Task t = new Task();   taskStatus.put(t, TaskStatus.NOT_STARTED);   exec.execute(t);   return t;   }  }--------------------------------------------------------------
--------------------------------------------------------------
1。主要讨论一下,除了上面两种导致java内存泄露,其它的情况?
2。关于代码 private Map<Socket,User> m = new HashMap<Socket,User>();
   (用尖括号)这种写法是jdk1.5后才出现的?换个写法是什么样的?

解决方案 »

  1.   

    补充一下private Map <Socket,User> m = new HashMap <Socket,User>(); 
    (用尖括号)这种写法到底是什么意思?
      

  2.   

    private Map <Socket,User> m = new HashMap <Socket,User>(); 
    其实是泛型,这样就指出啦Map 中key,value的类型是Socket,User
    使得调用如m.get(key),就直接得到Socket类型对象
    这样就免去了类型检查和强制转换,安全性好jdk1.5 以前,没有泛型,就这样声明
    private Map m = new HashMap ();
    这样key,value 都当成Object对象存进去
    拿出来时,就得强制转换,Socket tmp = (Socket)m.get(key);
    因为m.get(key) 返回的是Object 对象,这样安全性显然不好
    因为你也可以  User tmp = (User) m.get(key); 而不会报错当然在jdk1.5 也可以 这样private Map m = new HashMap ();
    不过会有warning,最好使用泛型
      

  3.   

    java 比C++ 安全的一个原因就是程序员不必担心
    内存泄露的问题,由垃圾回收机制帮你处理,
    但如果它失效,那么就会有内存泄露,lz可以去看看
    垃圾回收机制的内容
      

  4.   

    回复3楼朋友小杰:
        有两个问题第一Socket tmp = (Socket)m.get(key);  这种方法取map里的数据为什么说他会是不安全的?是否由于m.get(key)可能取到的是null
        第二private Map <Socket,User> m = new HashMap <Socket,User>(); 取这里的key值如下这样取--socket=m.get(user);  里面的user对象相当于key值,而socket就相当于是value ?
      

  5.   


    因为你拿出来时,你强制转换时的类型可能和你存进去时的类型可能不一致,所以不安全
    我之前好像把你这个例子的key 和 value 的类型倒转啦
    你对换一下去理解吧