程序员基本功04JAVA的内存回收

读书笔记自己看的(O_O)

1、Java引用的功能和意义

程序员需要通过关键字new创建Java对象,即可视作为Java对象申请内存空间,JVM会在堆内存中为每个对象分配空间;当一个Java对象失去引用,Java回收机制会自动清除它们。

2、Java引用与内存回收之间的关系

只要还有引用变量引用该对象,垃圾回收机制就不会回收它。Java对象被创建出来后,垃圾回收机制会实时地监控每一个对象的运行状态,当垃圾回收机制监控到某一个对象不再被引用变量所引用时,立即回收机制就会回收它所占的空间。

JVM的垃圾回收机制采用有向图方式管理内存中的对象,可以方便的解决循环引用问题。采用有向图来管理内存中的对象具有较高的精度,但效率较低。

3、Java对象在内存中的不同状态

可达状态:有一个以上的引用变量引用它,程序可以通过引用变量来调用该对象的属性和方法。

可恢复状态:程序中的对象不在有程序引用它。它将先进入可恢复状态,回收机制准备回收该对象所占内存。在回收之前,系统会调用finalize方法进行资源清理,如果系统在调用finalize方法重新让变量引用该对象,这个对象会变成可达状态。

不可达状态:该对象的所有关联都被切断,且系统调用finalize方法依然没有使该对象变成可达状态,那么该对象将永久性失去引用。

当某个对象被其他类的类变量引用时,只有该类被销毁后,该对象才会进入可恢复状态;当某个对象被其他对象的实例变量引用时,只有当引用该对象的对象被销毁或变成不可达状态后,该对象才会进入不可达状态。

程序创建一个对象,并把这个对象赋给一个引用变量,这个就是强引用,JVM不会回收强引用的Java对象,因此强引用是造成内存泄漏的主要原因之一。

4、软引用的作用和使用软引用的注意点

软引用需要通过SoftReferance类来实现,当系统内存空间足够时,对于只有软引用的对象而言,它不会被回收,当内存不足时,系统将会回收它。软引用通常用于内存敏感的程序中,解决内存紧张的难题。

5、弱引用的作用和使用弱引用的注意点

弱引用和软引用相似,使用WeakReferancd类实现,只是弱引用生存期更短,当垃圾回收机制运行时,不管系统内存够不够,总会回收该对象所占内存。

弱引用具有很大的不确定性,因为每次垃圾回收机制执行时都会回收弱引用所引用的对象,而垃圾回收机制不受程序员控制,因此程序获取弱引用所引用的Java对象时必须小心空指针异常。

6、虚引用的作用和需引用的注意点

虚引用不能单独使用,必须和引用队列(ReferenceQueue)联合使用。虚引用的主要作用是跟踪对象被垃圾回收的状态,程序可以通过检查与虚引用关联的引用队列中是否已经包含指定虚引用,从而了解虚引用所引用对象是否即将被回收。

7、Java内存泄漏原因

内存泄漏:程序运行过程中会不断分配内存空间,哪些不再使用的内存空间应该及时回收它们,从而保证系统能再次使用这些内存,如果存在无用的内存没有被回收,那就是内存泄漏。

不可达的对象由垃圾回收机制进行回收,如果程序中的一些对象处于可达状态,但程序永远都不会访问它们,那么它们所占的内存也不会被回收,从而造成内存泄漏。

8、Java内存泄漏和C++内存泄漏的差异

对于C++而言,对象占用的内存空间必须由程序员显示的回收,程序员可在合适的时机释放它们。但是,Java程序来说,只要它们一直处于可达状态,垃圾回收机制就不会回收它们。

9、Java内存回收机制的基本算法

垃圾回收机制主要完成俩件事:跟踪并监控每个Java对象,当某个对象处于不可达状态时,回收该对象所占的内存;清理内存分配,回收过程中产生的内存碎片。这俩个工作量都不小,因此垃圾回收算法成为限制Java运行效率的重要原因,实现高校JVM的一个重要方面就是提供高校的垃圾回收机制。

JVM垃圾回收机制判断某个对象是否可以回收的唯一标准是:是否还有其他引用指向该对象。实际上,当一个对象失去引用后,它不会被立即回收,只有等垃圾回收运行时才会被回收。

https://www.cnblogs.com/sunniest/p/4575144.html(垃圾回收算法)

10、堆内存的分代回收

分代回收的策略基于俩点:绝大多数对象不会被长时间引用,这些对象在young代期间就会被回收;很老的对象和很新的对象之间很少存在相互引用的情况。对于young代的对象而言,大部分对象都会很快进入不可达状态,少数对象能熬到垃圾回收执行时,如果采用复制算法,只需要少量的复制成本,因此大部分垃圾回收器对young代都采用复制算法。

11、Young代、Old代和Permanent代的各自存储对象

对young代采用复制算法只需遍历那些处于可达状态的对象;

old代的垃圾回收具有俩个特征:old代垃圾回收的执行频率无需太高,因为很少有对象死掉;每次对old代执行垃圾回收需要更长的时间来完成。随着时间的流逝,old代的对象会越来越多,因此old代的空间比young代空间更大。

12、Young代、Old代和permanent代的特定及适用的回收算法

对young代使用复制算法

对于old代,通常采用标记压缩算法,这种算法可以避免复制old代的大量对象

垃圾回收机制通常不会回收permanent代中的对象。

13、常见垃圾回收机制对堆内存的回收细节

串行回收器:串行回收器对young代和old代的回收都是串行的,垃圾回收期间程序会暂停,具体策略为,young代采用串行复制算法,old代采用串行标记压缩算法。系统将Eden中的活动对象直接复制到To区,如果对象占用内存特别大,垃圾回收器会直接将其复制到old中。对于From区的活动对象,如果生存时间长,它将被复制到old代中,否则将被回收到To区中。完成复制后,Eden和From区剩下的均为不可达的对象,由系统直接回收,To区保存了活动对象,在下一次回收时,原To区变为From区,原From区变为To区。

并行回收器:并行回收器对于young代采用与串行回收器基本象失的算发,只是增加了cpu并行能力,即同时启动多线程并行来执行垃圾回收。并行回收器对于old代采用与串行回收器完全相同的回收算法,采用单线程、标记整理的方式进行回收。

并发压缩回收器:对于young代,采用与并发回收器完全相同的算法;()

并发标识-清理回收器(CMS):

 

14、设计开发内存管理的小技巧

尽量使用直接量:

使用StringBuilder和StringBuffer进行字符串连接:String代表不可变字符串,而StringBuilder和StringBuffer代表字符序列可变的字符串

尽早释放无用对象的引用;

尽量少用静态变量:JVM会将含有静态变量的类存入到permanent代,这将导致

避免在经常调用的方法、循环中创建Java对象

缓存经常使用的对象:使用HashMap进行缓存,直接使用某些开源的缓存项目

尽量不要使用finalize方法:垃圾回收器本省已经严重制约程序性能,如果再使用finalize()进行资源清理,这将导致垃圾回收器负担更大,效率更差

考虑使用SoftReference:内存够时,它等同于普通引用,内存不够时,它会牺牲自己,释放内存

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值