这个问题自己本来应该会的,就是进行内存回收的出现了问题,但是一时没有反应过来。至于具体的信息需要参考java的内存模型:https://blog.csdn.net/huifeidezhu521/article/details/105289220
Java是如何管理内存
java的内存管理就是对象的分配与释放问题。分配就是程序运行进行,释放就是GC回收,当然可以手动释放。不管哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址。GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控,当然同时它也加重了JVM的工作,这也是 Java 程序运行速度较慢的原因之一。
为何出现内存泄漏
GC本来应该回收对象,但是因为其他的一些引用导致回收失败,所以该对象会一直停留在堆内存中。
常见的内存泄漏
单例加载在方法去,在生命周期中和应用一样,按照类的加载方式,一旦单例持有某个对象的引用,就会使得该对象不能被正常回收,从而导致了内存泄漏。
// 使用了单例模式
//在加载单例发现引用context,就会进行加载。
//这种属于长生命周期的对象持有短生命周期对象的引用。
public class AppManager {
private static AppManager instance;
private Context context;
private AppManager(Context context) {
this.context = context;
}
public static AppManager getInstance(Context context) {
if (instance != null) {
instance = new AppManager(context);
}
return instance;
}
}
各种链接
比如数据库连接(dataSourse.getConnection()),除非其显式的调用了其close()方法将其连接关闭,否则是不会自动被GC 回收的。对于Resultset 和Statement 对象可以不进行显式回收,但Connection 一定要显式回收,因为Connection 在任何时候都无法自动回收,而Connection一旦回收,Resultset 和Statement 对象就会立即为NULL。但是如果使用连接池,情况就不一样了,除了要显式地关闭连接,还必须显式地关闭Resultset Statement 对象(关闭其中一个,另外一个也会关闭),否则就会造成大量的Statement 对象无法释放,从而引起内存泄漏。这种情况下一般都会在try里面去的连接,在finally里面释放连接。
- 在使用数据库连接之初,强调的也是要进行数据库连接的手动关闭,释放资源。
- 使用连接池的时候,为提高数据库连接效率,会一直打开使用即可,无需关闭。