清单 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后才出现的?换个写法是什么样的?
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
清单 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后才出现的?换个写法是什么样的?
(用尖括号)这种写法到底是什么意思?
其实是泛型,这样就指出啦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,最好使用泛型
内存泄露的问题,由垃圾回收机制帮你处理,
但如果它失效,那么就会有内存泄露,lz可以去看看
垃圾回收机制的内容
有两个问题第一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 ?
因为你拿出来时,你强制转换时的类型可能和你存进去时的类型可能不一致,所以不安全
我之前好像把你这个例子的key 和 value 的类型倒转啦
你对换一下去理解吧