1、概述:垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存。
内存泄漏的定义:对象已经没有被应用程序使用,但是垃圾回收器没办法移除它们,因为还在被引用着。该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离
1、特别注意一些像HashMap、ArrayList的集合对象,它们经常会引发内存泄漏。当它们被声明为static时,它们的生命周期就会和应用程序一样长。 2、特别注意事件监听和回调函数。当一个监听器在使用的时候被注册,但不再使用之后却未被反注册。 3、如果一个类自己管理内存,那开发人员就得小心内存泄漏问题了。” 通常一些成员变量引用其他对象,初始化的时候需要置空。
Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
- 引用计数法
概述:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器都为0的对象就是不再被使用的,垃圾收集器将回收该对象使用的内存。 - 复制算法
S0和S1将可用内存按容量分成大小相等的两块,每次只使用其中一块,当这块内存使用完了,就将还存活的对象复制到另一块内存上去,然后把使用过的内存空间一次清理掉。这样使得每次都是对其中一块内存进行回收,内存分配时不用考虑内存碎片等复杂情况,只需要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。复制算法的缺点显而易见,可使用的内存降为原来一半。 - 标记清除算法
标记-清除(Mark-Sweep)算法顾名思义,主要就是两个动作,一个是标记,另一个就是清除。
标记就是根据特定的算法(如:引用计数算法,可达性分析算法等)标出内存中哪些对象可以回收,哪些对象还要继续用。
标记指示回收,那就直接收掉;标记指示对象还能用,那就原地不动留下。 - 标记-压缩算法
标记压缩法在标记清除基础之上做了优化,把存活的对象压缩到内存一端,而后进行垃圾清理。(java中老年代使用的就是标记压缩法) 分代收集算法
根据内存中对象的存活周期不同,将内存划分为几块,java的虚拟机中一般把内存划分为新生代和年老代,当新创建对象时一般在新生代中分配内存空间,当新生代垃圾收集器 回收几次之后仍然存活的对象会被移动到年老代内存中,当大对象在新生代中无法找到足够的连续内存时也直接在年老代中创建。对于新生代和老年代来说,新生代回收频率很高,但是每次回收耗时很短,而老年代回收频率较低,但是耗时会相对较长,所以应该尽量减少老年代的GC.Java垃圾回收器是Java虚拟机(JVM)的三个重要模块(另外两个是解释器和多线程机制)之一,为应用程序提供内存的自动分配(Memory Allocation)、自动回收(Garbage Collect)功能,这两个操作都发生在Java堆上(一段内存快)。某一个时点,一个对象如果有一个以上的引用(Rreference)指向它,那么该对象就为活着的(Live),否则死亡(Dead),视为垃圾,可被垃圾回收器回收再利用。垃圾回收操作需要消耗CPU、线程、时间等资源,所以容易理解的是垃圾回收操作不是实时的发生(对象死亡马上释放),当内存消耗完或者是达到某一个指标(Threshold,使用内存占总内存的比列,比如0.75)时,触发垃圾回收操作。有一个对象死亡的例外,java.lang.Thread类型的对象即使没有引用,只要线程还在运行,就不会被回收。
单线程执行回收操作,回收期间暂停所有应用线程的执行,client模式下的默认回收器,通过-XX:+UseSerialGC命令行可选项强制指定。
并行回收器在串行回收器基础上做了改进,他可以使用多个线程同时进行垃圾回收,对于计算能力强的计算机而言,可以有效的缩短垃圾回收所需的尖际时间。
ParNew回收器是一个工作在新生代的垃圾收集器,他只是简单的将串行回收器多线程快他的回收策略和算法和串行回收器一样。使用XX:+UseParNewGC 新生代ParNew回收器。老年代ParallelOldGC回收器也是一种多线程的回收器,和新生代的ParallelGC回收器一样,也是一种关往吞吐量的回收器,他使用了标记压缩算法进行实现。
-XX:+UseParallelOldGC 进行设置
-XX:+ParallelCThread也可以设置垃圾收集时的线程教量。- Jmeter压力测试工具
调优总结
初始堆值和最大堆内存内存越大,吞吐量就越高。
最好使用并行收集器,因为并行手机器速度比串行吞吐量高,速度快。
设置堆内存新生代的比例和老年代的比例最好为1:2或者1:3。
减少GC对老年代的回收。
来源:博客园
作者:小鱼。。
链接:https://www.cnblogs.com/Libbo/p/11470555.html