Jvm内存区以及垃圾回收算法
2017-03-12 10:32
429 查看
Java虚拟机运行时数据区域被分为五个区域:堆(Heap)、栈(Stack)、本地方法栈(Native Stack)、方法区(Method Area)、程序计数器(Program Count Register)
CMS(Concurrent Mark-Sweep)是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器,如果你的应用程序对停顿比较敏感,并且在应用程序运行的时候可以提供更大的内存和更多的CPU(也就是硬件牛逼),那么使用CMS来收集会给你带来好处。还有,如果在JVM中,有相对较多存活时间较长的对象(老年代比较大)会更适合使用CMS。
G1为了能够尽量的做到准实时的响应,例如估算暂停时间的算法、对于经常被引用的对象的特殊处理等,G1为了能够让GC既能够充分的回收内存,又能够尽量少的导致应用的暂停,可谓费尽心思,从G1的论文中的性能评测来看效果也是不错的,不过如果G1能允许开发人员在编写代码时指定哪些对象是不用mark的就更完美了,这对于有巨大缓存的应用而言,会有很大的帮助,G1将随JDK 6 Update 14 beta发布。
并行收集:并行收集使用多线程处理垃圾回收工作,因而速度快,效率高。而且理论上CPU数目越多,越能体现出并行收集器的优势。(串型收集的并发版本,需要暂停jvm) 并行paralise指的是多个任务在多个cpu中一起并行执行,最后将结果合并。效率是N倍。
堆 Java Heap是Java虚拟机管理的内存的最大一块,这块区域随着虚拟机的启动而创建。在实际的运用中,我们创建的对象和数组就是存放在堆里面。 如果你听说线程安全的问题,就会很明确的知道Java Heap是一块共享的区域,操作共享区域的成员就有了锁和同步。 与Java Heap相关的还有Java的垃圾回收机制(GC),Java Heap是垃圾回收器管理的主要区域。程序猿所熟悉的新生代、老生代、永久代的概念就 是在堆里面,现在大多数的GC基本都采用了分代收集算法。如果再细致一点,Java Heap还有Eden空间,From Survivor空间,To Survivor空间等。 栈(Stack) Java Stack是线程私有的,她的生命周期与线程相同。Java Stack描述的是Java方法执行时的内存模型,每个方法执行时都会创建一个栈帧(Stack Frame) 用语存储局部变量表、操作数栈、动态链接、方法出口 本地方法栈 本地方法栈(Native Stack)与Java虚拟机站(Java Stack)所发挥的作用非常相似,他们之间的区别在于虚拟机栈为虚拟机栈执行java方法(也就是字节码) 服务,而本地方法栈则为使用到Native方法服务 方法区:很多人都更愿意把方法区称为“永久 方法区(Method Area)与堆(Java Heap)一样,是各个线程共享的内存区域,它用于存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据 线程私有的数据区域有: Java虚拟机栈(Java Stack) 本地方法栈(Native Stack) 线程共有的数据区域有: 堆(Java Heap) 方法区 堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。 堆的大小可以通过参数 –Xms、-Xmx 来指定。 新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2( 该值可以通过参数 –XX:NewRatio 来指定 ) 新生代 ( Young ) = 1/3 的堆空间大小。 老年代 ( Old ) = 2/3 的堆空间大小。 新生代 ( Young ) 被细分为 Eden 和 两个 Survivor 区域,这两个 Survivor 区域分别被命名为 from 和 to,默认的Edem : from : to = 8 : 1 : 1 JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块 Survivor 区域是空闲着的。 GC 分为两种:Minor GC、Full GC ( 或称为 Major GC )。 1.Minor GC 是发生在新生代中的垃圾收集动作,所采用的是复制算法。 a、新生代几乎是所有 Java 对象出生的地方,即 Java 对象申请的内存以及存放都是在这个地方。 b、Java 中的大部分对象通常不需长久存活,具有朝生夕灭的性质。 c、当一个对象被判定为 “死亡” 的时候,GC 就有责任来回收掉这部分对象的内存空间。 d、新生代是 GC 收集垃圾的频繁区域。 e、当对象在 Eden(+from) 出生后,在经过一次 Minor GC 后,如果对象还存活,并且能够被另外一块 Survivor 区域 所容纳( 这里应为 to 区域 ),则使用复制算法将这些仍然还存活的对象复制到另外一块 Survivor 区域 ( 即 to 区域 ) 中, f、 然后清理所使用过的 Eden 以及 Survivor 区域 ( 即 from 区域 ),并且将这些对象的年龄设置为1, g、以后对象在 Survivor 区每熬过一次 Minor GC,就将对象的年龄 + 1, h、当对象的年龄达到某个值时 ( 默认是 15 岁,可以通过参数 -XX:MaxTenuringThreshold 来设定 ),这些对象就会成为 老年代。 j、但这也不是一定的,对于一些较大的对象 ( 即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代。 复制算法 1、将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。 2、当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。 2.Full GC 是发生在老年代的垃圾收集动作,所采用的是标记-清除算法。 a、老年代里面的对象几乎个个都是在 Survivor 区域中熬过来的,它们是不会那么容易就 “死掉” 了的。 b、Full GC 发生的次数不会有 Minor GC 那么频繁,并且做一次 Full GC 要比进行一次 Minor GC 的时间更长。 c、标记-清除算法收集垃圾的时候会产生许多的内存碎片 ( 即不连续的内存空间 ), d、此后需要为较大的对象分配内存空间时,若无法找到足够的连续的内存空间,就会提前触发一次 GC 的收集动作。 1、标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象 2、在标记完成后统一回收所有被标记的对象 内存分配与回收策略 下面是使用Serial/Serial Old收集器下(ParNew/Serial Old收集器组合的规则也基本一致)的内存分配和回收的策略 对象优先在Eden分配 1、大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次MinorGC。 2、执行GC后,将存活的对象分配到Survivor空间 3、无法放到Survivor空间的对象,分配到老年代 4、分配到Survivor的对象,经过15次Minor GC后,进入老年代 新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。 老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的MinorGC(但非绝对的,在Parallel Scavenge收集器的 收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上 大对象直接进入老年代 1、大对象:需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串以及数组 2、虚拟机提供了一个-XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接在老年代分配 长期存活的对象将进入老年代 1、虚拟机给每个对象定义了一个对象年龄(Age)计数器 2、如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1。 3、对象在Survivor区中每“熬过”一次Minor GC,年龄就增加1岁 4、当它的年龄增加到一定程度(默认为15岁),就将会被晋升到老年代中 5、对象晋升老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold设置 动态对象年龄判定 1、为了能更好地适应不同程序的内存状况,虚拟机并不是永远地要求对象的年龄必须达到了MaxTenuringThreshold才能晋升老年代 2、如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄 4. 并行垃圾回收收集器和CMS收集器区别
CMS(Concurrent Mark-Sweep)是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器,如果你的应用程序对停顿比较敏感,并且在应用程序运行的时候可以提供更大的内存和更多的CPU(也就是硬件牛逼),那么使用CMS来收集会给你带来好处。还有,如果在JVM中,有相对较多存活时间较长的对象(老年代比较大)会更适合使用CMS。
G1为了能够尽量的做到准实时的响应,例如估算暂停时间的算法、对于经常被引用的对象的特殊处理等,G1为了能够让GC既能够充分的回收内存,又能够尽量少的导致应用的暂停,可谓费尽心思,从G1的论文中的性能评测来看效果也是不错的,不过如果G1能允许开发人员在编写代码时指定哪些对象是不用mark的就更完美了,这对于有巨大缓存的应用而言,会有很大的帮助,G1将随JDK 6 Update 14 beta发布。
并行收集:并行收集使用多线程处理垃圾回收工作,因而速度快,效率高。而且理论上CPU数目越多,越能体现出并行收集器的优势。(串型收集的并发版本,需要暂停jvm) 并行paralise指的是多个任务在多个cpu中一起并行执行,最后将结果合并。效率是N倍。
相关文章推荐
- Java之JVM垃圾回收 内存结构以及垃圾回收算法
- JVM内存组成结构分配以及垃圾回收策略和算法
- Java之JVM垃圾回收 内存结构以及垃圾回收算法
- JVM内存回收算法以及垃圾收集器
- 【java】---JVM内存模型以及垃圾回收算法
- JVM内存模型及垃圾回收算法
- JVM内存模型及垃圾回收算法
- JVM内存模型及垃圾回收算法
- JVM内存模型及垃圾回收算法
- 【转】JVM内存模型以及垃圾回收
- JVM内存模型以及垃圾回收
- 内存管理机制-JVM 垃圾回收算法
- JVM内存模型及垃圾回收算法
- JVM内存模型以及垃圾回收
- JVM内存模型及垃圾回收算法
- JVM内存模型以及垃圾回收
- JVM内存模型及垃圾回收算法
- JVM内存模型以及垃圾回收
- JVM结构、内存分配、垃圾回收算法、垃圾收集器