JVM内存管理:Java中常见内存泄漏案例
在Java中,内存泄漏通常是指程序在申请内存后,无法释放已使用的内存空间,导致系统可用内存逐渐减少。
以下是一些常见的内存泄漏案例:
- 静态变量引用:如果一个静态变量被一个线程持有,那么当这个线程结束时,静态变量仍然被引用,导致内存泄漏。例如:
public class StaticRefLeak {
static ThreadLocal<String> local = new ThreadLocal<>();
public void run() {
while (true) {
String value = "test";
local.set(value);
// 打印以验证内存使用
System.out.println("Value: " + value);
// 这里可以添加睡眠来模拟耗时操作
try {
Thread.sleep(1000); // 1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread thread = new Thread(new StaticRefLeak().run());
thread.start(); // 启动线程
}
}
- 多线程共享数据:如果多个线程同时访问和修改一个共享对象,如果没有正确同步,可能会导致内存泄漏。例如使用
synchronized
关键字:
public class SharedObjectLeak {
private Object sharedObj;
public void setSharedObj(Object obj) {
synchronized (this) { // 使用synchronized进行同步
this.sharedObj = obj;
}
}
// 在多线程环境中调用该方法,可能会导致内存泄漏
public void useSharedObj() {
Object retrievedObj = sharedObj; // 不加同步可能泄露
System.out.println("Retrieved object: " + retrievedObj);
}
public static void main(String[] args) {
SharedObjectLeak leakObj = new SharedObjectLeak();
Thread thread1 = new Thread(() -> {
leakObj.setSharedObj(new Object());
}));
Thread thread2 = new Thread(() -> {
leakObj.useSharedObj(); // 这里可能会导致内存泄漏
}));
thread1.start();
thread2.start();
// 等待线程结束,这里可以添加超时时间来提高效率
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
通过以上案例分析,了解Java内存泄漏的常见原因和解决方法。
还没有评论,来说两句吧...