[Effective Java] - 2,内存泄露
来源:互联网 发布:免费排八字软件 编辑:程序博客网 时间:2024/06/05 03:03
JVM为Java提供了自动垃圾回收机制,但是往往很多时候总是会发生内存泄露。
仔细研究出栈pop()操作你会发现,栈中存在大量的无法被引用到的对象,因为出栈之后并没有将元素标记为不再使用,这些在size之后的元素就成了无法被访问的无效引用对象,但是由于stack栈对象本身还是有效引用,因此这些无效的引用无法被垃圾回收器回收,造成内存泄漏。
内存泄露 : 不再继续被应用程序使用的对象持续占用内存,得不到释放。当某个对象不可达时,就应该回收该对象的内存,否则内存泄露。
下面这个代码会发生内存泄露。
public class Stack{ private Object[] elements; private int size = 0; private static final int DEFAULT_SIZE = 15; public Stack(){ elements = new Object[DEFAULT_SIZE]; } public void push(Object o){ ensureCapatity(); elements[size++] = o; } public Object pop(){ if(size == 0){ throw new EmptyStackException(); } return elements[--size]; } //如果栈已满,则将容量扩大一倍 public ensureCapatity(){ if(elements.length == size){ elements = Arrays.copyOf(elements, 2 * size + 1); } } }
仔细研究出栈pop()操作你会发现,栈中存在大量的无法被引用到的对象,因为出栈之后并没有将元素标记为不再使用,这些在size之后的元素就成了无法被访问的无效引用对象,但是由于stack栈对象本身还是有效引用,因此这些无效的引用无法被垃圾回收器回收,造成内存泄漏。
代码修改如下:切断无效的引用对象,将其设置为null。
public Object pop(){ if(size == 0){ throw new EmptyStackException(); } Object result = elements[--size]; elements[size] = null;//将已经出栈的元素置为null,垃圾回收器就会清理这些对象 return result; }
- 避免内存泄露的小技巧
- a. 尽量使用直接量,对于Byte、Short、Integer、Long、Float、Double、Bolean、Character程序不应该使用new 方式创建对象,而采用直接量创建它们。
- b. 使用StringBuilder和StringBuffer进行字符串连接
- Sting和StringBuilder以及StringBuffer等都可以代表字符串,其中String字符串代表的是不可变的字符串,后两者表示可变的字符串。
- 如果使用多个String对象进行字符串连接运算,在运行时可能产生大量临时字符串,这些字符串会保存在内存中从而导致程序性能下降。
- c. 尽量少使用静态变量
- 类的静态变量的生命周期和类同步的。在类不被卸载的情况下,类对应类对象会常驻内存,知道程序运行结束。
- 如下代码就会存在内存泄露问题:
- class Person
- {
- static Object obj = new Object();
- }
- d.避免在经常调用的方法、循环中创建Java对象。
- e. 缓存经常使用的对象
- 如果有些对象需要经常被用到,可以考虑把这些对象用缓存池保存起来,下次用的时候直接从池中拿。典型的就是数据连接池。
- 如果系统中还有一些常用的基础信息,可以考虑用缓存,实现缓存的方式有如下两种:
- (1) 使用HashMap进行缓存。
- (2) 直接使用某些开源的缓存项目。
- 说明:缓存设计本身就是一直以牺牲系统空间来换取运行时间的技术。
- f. 考虑使用SoftReference
- 当程序需要创建长度很大的数组时,可以考虑使用SoftReferene来包装数组元素,而不是直接让将数组元素来引用对象。此时SoftReference是个很好的选择:当内存足够时,它的功能等同于普通引用;当内存不足时,它会牺牲自己,释放软引用所引用的对象。
- 注意:由于软引用引用对象的不确定性(软引用所获取的对象可能为null),所以程序取出SoftReference所引用的Java之后,应该显式判断该对象是否为null; 当该对象为null时,应该重建该对象。
0 0
- [Effective Java] - 2,内存泄露
- NO6 java内存泄露 effective JAVA 笔记
- JAVA内存泄露(Effective java学习)
- 关于java内存泄露2--内存泄露示例
- Effective java2——内存泄露
- Java内存泄露问题
- Java内存泄露问题
- java的内存泄露
- 关于java内存泄露
- Java内存泄露
- Java内存泄露
- Java内存泄露
- java内存泄露
- java内存泄露(转)
- java内存泄露
- Java内存泄露
- java的内存泄露
- java内存泄露解析
- UIScrollView的基本设置
- pythoneer 的三大神器—fabric
- 机载导航系统的发展小整理
- Android Studio导入项目的中文注释乱码解决方法
- Mac 上tomcat的安装
- [Effective Java] - 2,内存泄露
- Windows下使用VisualSVN Server搭建SVN服务器
- ndroid:StatFs类 获取系统/sdcard存储空间信息
- php 查看代码执行时间
- Android网络请求框架AsyncHttpClient详解
- Struts2环境配置
- 增强for循环
- spring boot security csrf ignore
- JAVA PAT-1003