Java的核心优势之一就是利用JVM(Java虚拟机),JVM是一种开箱即用的内存管理。你只管创建对象,Java的垃圾回收器帮你分配以及回收内存。然而,实际的情况并没有那么简单,因为内存泄漏在Java应用程序中还是时有发生的。
为了避免内存泄漏,你需要注意如何编写代码。以下是帮助你消除内存泄漏的具体方法。
1.使用引用对象避免内存泄漏
JavaWorld的RaimondRichert写道,你可以使用引用对象来消除内存泄漏。
使用java.lang.ref包,可以在程序中使用垃圾收集器。这允许你避免直接引用对象,并使用垃圾收集器容易清除的特殊引用对象。特殊的子类允许你间接引用对象。例如,Reference有三个子类:PhantomReference、SoftReference和WeakReference。
可以使用引用对象的get方法访问引用对象或这些子类引用的对象。使用此方法的优点是,通过将引用设置为null,可以轻松地清除引用,并且引用几乎是不可变的。垃圾收集器如何处理每种类型的引用?
l SoftReference对象:当内存不足时,需要垃圾收集器清除所有SoftReference对象。
l WeakReference对象:当垃圾收集器检测到弱引用对象时,对它的所有引用都将被清除,并最终从内存中取出。
l PhantomReference对象:垃圾收集器无法自动清理PhantomReference对象,因此只能手动清理所有PhantomReferences对象和引用。
使用引用对象,可以使用垃圾收集器自动执行删除弱可访问侦听器的任务。WeakReference对象,尤其是清理线程,可以帮助你避免内存错误。
![](https://i-blog.csdnimg.cn/blog_migrate/df4076d951464d2235637ab1b530709f.png)
2.避免与WebApp类加载器相关的内存泄漏
使用码头7.6.6。或更高版本,你可以防止WebApp类加载器固定。当代码不断引用WebApp类加载器时,内存泄漏很容易发生。在这种情况下有两种类型的泄漏:守护进程线程和静态字段。
静态字段以类加载器的值开始。即使Jetty停止部署并重新部署web应用程序,静态引用仍然存在,因此无法从内存中清除对象。
在web应用程序生命周期之外启动的守护程序线程,由于这些线程引用了启动线程的类加载器,因此容易发生内存泄漏。
使用Jetty,你可以使用预防器来帮助你解决与WebApp类加载器相关的问题。例如,appcontext.getappcontext()等应用程序上下文泄漏防止器可以帮助你将静态引用保存在上下文类加载器中。在Java培训中,有更加系统全面的课程,明确清晰的学习路线,学习起来既轻松,又高效。
你可以使用的其他防护装置包括:
AWT防泄漏器
DOM防泄漏器
驾驶员经理防泄漏器
GC螺纹防泄漏器
Java2D防泄漏器
LDAP防泄漏器
登录配置防泄漏器
安全提供商防泄漏器
![](https://i-blog.csdnimg.cn/blog_migrate/7ebe091adbabf937a3c0b61c4ef43536.png)
3.其他具体步骤
还有几种防止Java内存泄漏的方法,包括:
l 不再需要时,释放会话。使用HttpSession.invalidate()执行此操作。
l 保持每个会话的超时时间较低。
l 在HttpSession中只存储必要的数据。
l 避免使用字符串串联。使用StringBuffer的append()方法,因为字符串是不可更改的对象,而字符串串联会创建许多不必要的对象。大量临时对象会降低性能。
l 尽可能不要在jsp页面上创建HttpSession。你可以使用page指令<%@page session=“false”%>来执行此操作。
l 如果要编写频繁执行的查询,请使用PreparedStatement对象,而不是使用Statement对象。为什么?PreparedStatement是预编译的,而每次将SQL语句传输到数据库时都会编译Statement。
l 使用JDBC代码时,在编写查询时避免使用“*”。请尝试改用相应的列名。
l 如果要在循环中使用stmt=con.prepareStatement(SQL query ),请确保在特定循环中关闭它。
l 当需要重用语句和结果集时,请务必关闭它们。
l 关闭最终块中的ResultSet、Connection、PreparedStatement和Statement。
总结
Java 中的内存泄漏被认为是一种疾病,因为它们会阻碍资源的性能。如果他们不能及时修复或避免,随着时间的推移,可能会导致致命的应用程序崩溃。