理解并正确使用对象生命周期:
声明变量时尽量缩小作用域:在方法内部声明的局部变量会在方法执行完毕后自动由垃圾回收器回收。避免在类级别声明长期存在的对象引用。
public class MyClass {// 错误做法:全局静态变量可能导致内存泄漏// static List<Object> globalList = new ArrayList<>();public void processData() {// 正确做法:在方法内部创建需要的对象List<Object> dataList = new ArrayList<>();// 使用dataList...}
}
解除无用对象引用:
当不再需要某个对象时,应将其引用设为null,特别是对于集合、监听器和其他回调接口等场景。
public class MyActivity extends Activity {private SomeEventListener listener;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listener = new SomeEventListener();someObject.setListener(listener);// 在适当的时候如onDestroy或不再需要监听时解除引用@Overrideprotected void onDestroy() {super.onDestroy();someObject.setListener(null);listener = null; // 防止Activity销毁后仍有外部对象持有其内部匿名类引用导致泄漏}}
}
避免循环引用:
使用WeakReference、SoftReference等弱引用类型替代强引用,允许垃圾回收器回收即使存在引用关系的对象。
class Node {private Object data;private WeakReference<Node> nextNodeRef;public Node(Object data, Node nextNode) {this.data = data;this.nextNodeRef = new WeakReference<>(nextNode);}public void setNextNode(Node nextNode) {this.nextNodeRef = new WeakReference<>(nextNode);}public Node getNextNode() {return nextNodeRef.get();}
}
合理管理线程资源:
关闭不再使用的线程,确保其持有的所有资源能够被释放。
线程池中的工作线程不应当持有Activity或其他组件的直接引用。
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(new Task());// ...// 在任务完成后或者应用关闭时,关闭线程池以释放资源
executor.shutdown();
try {if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {executor.shutdownNow();}
} catch (InterruptedException ie) {executor.shutdownNow();
}
注意系统级资源的清理:
对于文件流、数据库连接、网络套接字等非JVM内存资源,在使用完后要确保调用了对应的关闭或释放方法。
FileInputStream fis = new FileInputStream("file.txt");
try {// 使用fis...
} finally {fis.close(); // 确保在finally块中关闭文件流
}
谨慎使用静态集合类存储对象:
如果静态集合用于存储实例,除非有特殊清理机制,否则其中的对象将无法被垃圾回收
public class Singleton {private static Map<String, HeavyObject> cache = new HashMap<>();public static HeavyObject get(String key) {HeavyObject obj = cache.get(key);if (obj == null) {obj = new HeavyObject();cache.put(key, obj);}// 注意在不再需要时从缓存移除对象,避免长期占用内存// 或者考虑使用有大小限制且有过期策略的缓存实现(如Google Guava的LoadingCache)return obj;}
}
使用适当的数据结构和框架特性:
许多现代Java库和框架提供了对内存管理友好的数据结构和功能,例如Android中的SparseArray代替普通的HashMap可以减少对强引用的需求。