java垃圾回收机制

java垃圾回收机制

标签(空格分隔): java 内存管理

      • java垃圾回收机制
        • 确定某个对象是否是垃圾
        • 垃圾收集算法
          • Mark-Sweep标记清除算法
          • Copying复制算法
          • Mark-Compact标记-整理算法
          • Generational Collection分代收集算法
        • java垃圾收集器
        • 内存分配

确定某个对象是否是垃圾

  • 引用计数
    通过引用和对象进行关联,如果要操作对象,则必须通过引用进行。如果一个对象没有任何对象与之关联,那么该对象基本不太可能在其他地方被使用,那么就可以被回收。但是它无法解决循环引用的问题。
  • 可达性分析搜索
    通过从GC Roots对象作为起点进行遍历搜索,搜索所走过的路径,称之为引用链,当一个对象到GC Roots没有任何引用链相连时,证明次对象是不可用的,即会被判定为可回收的对象。

垃圾收集算法

Mark-Sweep(标记-清除)算法
  • 这是最基础的算法,也是最容易实现与理解的算法,分为标记与清除2个阶段。标记阶段就是标记出所有需要被回收的对象,清除阶段就是回收被标记的对象所占的内存空间。
  • 优点:简单易实现
  • 缺点:容易产生内存碎片,导致后续为大对象分配内存时无法找到足够的空间而提前触发新的垃圾回收。
Copying(复制)算法
  • 为了解决Mark-Sweep(标记-清除)算法的缺陷,它将可用的内存区域分为想等的2块,每次只使用一块,当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉,这样一来就不容易出现内存碎片的问题。
  • 优点:实现简单,运行高效且不易产生内存碎片
  • 缺点:内存使用率不高,如果存活对象很多,那么Copying算法的效率将会大大降低。
Mark-Compact(标记-整理)算法
  • 同样分为2个阶段,标记阶段与整理阶段,完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存。
Generational Collection(分代收集)算法
  • 核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),老年代的特点是每次垃圾收集时只有少量对象需要被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,那么就可以根据不同代的特点采取最适合的收集算法。

  • 对于新生代都采取Copying算法,因为新生代中每次垃圾回收都要回收大部分对象,也就是说需要复制的操作次数较少,但是实际中并不是按照1:1的比例来划分新生代的空间的,一般来说是将新生代划分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将Eden和Survivor(From Space)中还存活的对象复制到另一块Survivor(To Space)空间中,然后清理掉Eden和刚才使用过的Survivor空间。

  • 而由于老年代的特点是每次回收都只回收少量对象,一般使用的是Mark-Compact算法。

  • 堆区之外还有一个代就是永久代(Permanet Generation),它用来存储class类、常量、方法描述等。对永久代的回收主要回收两部分内容:废弃常量和无用的类。

java垃圾收集器

垃圾收集器是垃圾内存回收的具体实现

  • Serial/Serial Old
    它是一个单线程收集器,并且它在进行垃圾收集的时,必 须暂停所有用户线程。
    Serial收集器是针对新生代的收集器,采用的是Copying算 法,Serail Old收集器针对的是老年代的收集器,采用的是Mar k-Compact算法。
    优点:实现简单高效
    缺点:暂停用户线程,带来停顿

  • ParNew
    它是Serial收集器的多线程版本,使用多个线程进行垃圾回收。

  • Parallel Scavenge
    它是一个新生代的多线程收集器,它在回收期间不需要暂停其他用户线程,采用的是Copying算法。该收集器与前两个收集器有所不同,它主要是为了达到一个可控的吞吐量。

  • Parallel Old
    它是Parallel Scavenge收集器的老年代版本(并行收集器),使用多线程和Mark-Compact算法。

  • CMS
    Current Mark Sweep。它是一种以获取最短回收停顿时间为目标的收集器,它是一种并发的收集器,采用的是Mark-Sweep算法。

  • G1
    它是一款面向服务端应用的收集器,它能充分利用CPU、多核环境。因此它是一款并行与并发收集器,并且它能建立可预测的停顿时间模型。

内存分配

  • 主要是堆内存上的分配问题,对象主要分配在新生代的Eden Space和From Space,少数情况下会直接分配在老年代。如果新生代的Eden Space和From Space的空间不足,则会进行GC,如果GC后,Eden Space和From Space能够容纳改对象就放在Eden Space和From Space,在GC的过程中,会将Eden Space和From Space中的存活对象移动到To Space,(Survivor区包括2个区From Space和To Space;新生代区也包括2个区Eden Space和Survivor区),然后将Eden Space 和From Space进行清理。如果清理过程中,To Space无法足够存储某个对象,就会将该对象移动到老年代中。这里的From 和To 是相对的,即进行了GC过后,下一次使用的就是Eden Space 和To Space了,下次GC后将存活的对象复制到From Space,如此循环,如果某个对象躲过一下清理,对象的年龄加1,默认情况下,对象年龄到达15岁,就会移动到老年代中。

  • 大对象会直接分配到老年代,所谓大对象就是指需要连续存储空间的对象,当然这种分配规则并不是百分之百固定的,取决与当前使用的垃圾收集器和JVM的相关参数

你可能感兴趣的:(java,算法,内存管理,内存分配)