public class MemoryLeakDemo {
private static final List<Object> staticList = new ArrayList<>();
public void addToList(Object obj) {
// 静态集合类持有对象引用,obj是短生命周期的对象
staticList.add(obj);
}
}
3. 单例模式
1.和静态集合导致内存泄漏的原因类似,由于单例的静态特性,其生命周期和JVM的生命周期一样长。
2.如果单例对象持有外部对象的引用,那么这个外部对象也不会被回收,从而造成内存泄漏。
3.举个例子
public class Singleton {
private List<Object> shortLivedObjects = new ArrayList<>();
// 单例对象
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
public void addShortLivedObject(Object obj) {
// 单例对象的shortLivedObjects持有短生命周期obj的引用
shortLivedObjects.add(obj);
}
}
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class Person {
private String name;
private int id;
public Person(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public int hashCode() {
return Objects.hash(name, id);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return id == person.id && Objects.equals(name, person.name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public static void main(String[] args) {
// 创建一个新的 Person 对象
Person person = new Person("Alice", 123);
// 创建一个 HashMap,将 Person 对象作为键
Map<Person, String> map = new HashMap<>();
map.put(person, "Person 1");
// 打印初始哈希值和映射
System.out.println("Initial hashCode: " + person.hashCode());
System.out.println("Initial map: " + map);
// 修改 Person 对象的 name 属性,从而改变其哈希值
person.setName("Bob");
// 打印修改后的哈希值和映射
System.out.println("Modified hashCode: " + person.hashCode());
System.out.println("Modified map: " + map);
// 尝试使用修改后的 Person 对象获取值
String value = map.get(person);
System.out.println("Value from map with modified key: " + value);
// 尝试移除修改后的 Person 对象
map.remove(person);
System.out.println("Map after removing modified key: " + map);
}
}
8. 缓存Cache泄漏
1.缓存对象未及时清理或没有设置合理的缓存策略,可能会导致内存泄漏。
2.举个例子
public class Cache {
private static final Map<String, Object> cache = new HashMap<>();
public void addToCache(String key, Object value) {
cache.put(key, value);
}
}
9. 监听器和回调
1.注册的事件监听器或回调未取消注册,导致对象无法被垃圾回收
2.举个例子
public class EventSource {
private List<EventListener> listeners = new ArrayList<>();
public void addListener(EventListener listener) {
listeners.add(listener);
}
// 未提供 removeListener 方法
}