垃圾收集器
java内存运行时区域的各个部分,其中程序计数器,虚拟机栈,本地方法栈3个区域随线程而生,随线程而亡。栈中的栈帧随着方法的进入和退出而有条不紊的执行着出栈和入栈的操作,每一个栈帧中分配多少内存基本上是在类结构确定下来时就已经是已知的。但是java堆和方法区不一样。垃圾收集器关注的也主要是这一部分。
常用的算法:
引用计数法,给对象添加一个累加器,每当有一个地方引用它时,计数器就加1,但是主流的虚拟机没有选用引用计数法来管理内存,其中最主要的原因是它很难解决对象之间的相互循环引用的问题。
可达性分析算法:可作为GC Roots的对象:虚拟机栈中引用的对象,方法区中类静态属性引用的对象,方法区中常量引用的对象,本地方法栈中native方法引用的对象。
很多人认为方法区(或者说是虚拟机中的永久代)是没有垃圾回收的,但是其实是存在的。永久代中的垃圾回收主要是两部分内容:废弃常量和无用的类。
G1收集器是目前当今收集器技术发展的最前沿的成果之一。具备以下特点:并行与并发。分代收集,空间整合,可预测的停顿。
新生代采用复制算法设计收集器,将内存分为一个较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor。当回收时,将Eden和Survivor还存活着的对象一次性地复制到另外一块Survivor空间上,最后清理掉Eden和刚才用过的Survivor空间。我们没有办法保证每次回收都只有不到百分之十的对象存活,当Survivor空间不够用时,需要依赖老年代进行分配担保。如果Survivor空间不能保存上一次新生代收集下来的存活对象时,这些对象将直接通过内存担保进入老年代。
老年代一般采用标记-整理的算法。
大多数情况下,对象在新生代Eden区分配,当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC。
新生代GC指发生在新生代的垃圾收集动作,因为java对象大多具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
老年代GC指发生在老年代的GC,出现了Major Gc,经常会伴有至少一次的GC,也就是Full GC。
大对象直接进入老年代,所谓的大对象是指需要大量的连续内存空间的java对象,最典型的大对象就是那种很长的字符串以及数组。
长期存活的对象将进入老年代。