随着计算机应用需求的日益增加,应用程序的设计与开发也相应的日趋复杂; 开发人员在程序实现的过程中处理的变量也大量增加,如何有效进行内存分配和释放,防止内存泄漏的问题变得越来越突出
例如: 服务器应用软件,需要长时间的运行,不断的处理由客户端发来的请求; 如果没有有效的内存管理,每处理一次请求信息就有一定的内存泄漏;这样不仅影响到服务器的性能,还可能造成整个系统的崩溃;因此,内存管理成为软件设计开发人员在设计中考虑的主要方面
以产生的方式来分类,内存泄漏可以分为四类:
发生内存泄漏的代码会被多次执行到,每次被执行时都会导致一块内存泄漏
发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生;常发性和偶发性是相对的; 对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要
发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅有一块内存发生泄漏
程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存; 严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存;但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存 所以,我们称这类内存泄漏为隐式内存泄漏
从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在; 真正有危害的是内存泄漏的堆积,这会最终耗尽系统所有的内存;从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到
总之内存泄漏原因太多了; 说不定就是某一行代码不对就会出现这种情况,关键的还是如何找出哪个地方出现了内存泄漏,代码好修改,错误不易查
代码运行结果如下:
静态变量的生命周期与程序一致;因此常驻内存
public class StaticTest {
public static List list = new ArrayList<>();
public void populateList() {
for (int i = 0; i < 10000000; i++) {
list.add((int)Math.random());
}
System.out.println("running......");
}
public static void main(String[] args) {
System.out.println("before......");
new StaticTest().populateList();
System.out.println("after......");
}
}
现在可以使用jvisualvm运行一边,看看内存效果
从上图可以看到,堆内存从一开始的135M左右飙升了到了200M。直接占据了65M的内存。
由于全局变量与程序周期不一致,因此不使用时,就会进行回收。此时内存最高150M。
总结:由于静态变量与程序生命周期一致,因此对象常驻内存,造成内存泄漏
每当建立一个连接,jvm就会为这么资源分配内存。比如数据库连接、文件输入输出流、网络连接等等
public class FileTest {
public static void main(String[] args) throws IOException {
File f=new File("G:nginx配套资料笔记资料.zip");
System.out.println(f.exists());
System.out.println(f.isDirectory());
}
}
依然使用jvisualvm运行一边,看看内存效果。
可以看出,在连接文件资源时,jvm会为本资源分配内存
ThreadLocal主要用于创建本地线程变量,不合理的使用也有可能会造成内存泄漏
上面这张图详细的揭示了ThreadLocal和Thread以及ThreadLocalMap三者的关系
重点来了,ThreadLocal是null了,也就是要被垃圾回收器回收了,但是此时我们的ThreadLocalMap生命周期和Thread的一样,它不会回收,这时候就出现了一个现象; 那就是ThreadLocalMap的key没了,但是value还在,这就造成了内存泄漏
解决办法:使用完ThreadLocal后,执行remove操作,避免出现内存溢出情况
代码层面的检查可以帮助发现部分内存泄漏的问题,但是生产环境中的内存泄漏往往不容易提前发现,因为很多问题是在大并发场景下才会出现;因此还需要通过压力测试工具进行压力测试,提前发现潜在的内存泄漏问题
有需要文中代码的同学,可以顺手给我点赞评论支持一下
获取方式: 私信发送"源码" ,即可 直达获取;现在私信还可获取一份 Android 开发系统性学习文档
PS:有问题欢迎指正,可以在评论区留下你的建议和感受;
欢迎大家点赞评论,觉得内容可以的话,可以转发分享一下
页面更新:2024-04-01
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号