首先本篇文章提到了内存泄漏。是指一些被实例化出后的对象不再被使用但是并没有被JVM中的垃圾回收机制回收。内存泄漏是发生在堆内存中的。
内存泄漏发生的原因:
1、类自己管理内存。对于一个栈,当栈顶指针下移elements[size++]=e,原栈顶元素被抛出后elements[--size],抛出的对象并没有显示,它还是存在于数组中原来的位置。只是指针不再指向它,他不再被调用 但是抛出的对象还是指向其他引用。对于这种情况 的解决办法是将抛出对象的值设置成elements[size]=null;数组也是同理,我们程序员自己将数组分成活动区域和非活动区域,但是JVM不会区分。JVM只会看整个数组是否正在被对象引用。但是不活动的对象中还是存在引用的,而且这个引用也可能指向多个对象,这些对象都不会被回收。只有当整个数组中的元素都被使用完毕后才有可能触发垃圾回收机制。所以需要设置null来消除过期对象的引用。
2、缓存。有些对象在缓冲区中会被遗忘,当缓存项的生命周期完全由外键决定时,WeakHashMap可以代表缓存。 对于一些过期缓存,WeakHashMap会将其自动删除。可以根据时间来删除缓存,因为缓存会随着时间而越来越没用,可以用LinkedhashMap中的removeEldestEntry来清理缓存。
3、监听器和其他回调。 一个监听器在使用的时候被注册,但是不再使用后却没有取消注册。会产生内存泄漏。解决办法:只保存他们的弱引用。比如:只将他们保存为WeakHashMap中的建。
WeakHashMap和HashMap的区别: 当WeakHashMap中除了自身对key的引用,key没有指向其他对象,那么此key会被回收。而HashMap不会。
强引用:通常我们通过new来创建一个新对象时返回的引用就是一个强引用,若一个对象通过一系列强引用可到达,它就是强可达的,那么它就不被回收
软引用:软引用和弱引用的区别在于,若一个对象是弱引用可达,无论当前内存是否充足它都会被回收,而软引用可达的对象在内存不充足时才会被回收,因此软引用要比弱引用“强”一些
虚引用:虚引用是Java中最弱的引用,那么它弱到什么程度呢?它是如此脆弱以至于我们通过虚引用甚至无法获取到被引用的对象,虚引用存在的唯一作用就是当它指向的对象被回收后,虚引用本身会被加入到引用队列中,用作记录它指向的对象已被回收。