当前位置: 首页 > news >正文

网站 设计 方案海南注册公司怎么注册

网站 设计 方案,海南注册公司怎么注册,工业园企业建设网站公司,把网站做静态化垃圾收集#xff08; Garbage Collection #xff0c;下文简称 GC#xff09;#xff0c;垃圾收集的历史远远比 Java久远。经过半个世纪的发展#xff0c;今天的内存动态分配与内存回收技术已经相当成熟#xff0c;一切看起来都进入了“自动化”时代#xff0c;那为什么… 垃圾收集 Garbage Collection 下文简称 GC垃圾收集的历史远远比 Java久远。经过半个世纪的发展今天的内存动态分配与内存回收技术已经相当成熟一切看起来都进入了“自动化”时代那为什么我们还要去了解垃圾收集和内存分配答案很简单当需要排查各种内存溢出、内存泄漏问题时当垃圾收集成为系统达到更高并发量的瓶颈时我们就必须对这些“自动化”的技术实施必要的监控和调节。 一、哪些内存需要回收 回答这个问题前需要先了解JVM到底有哪些内存区域可参考JVM运行时数据区域、内存溢出是怎样的_jvm 运行时数据区哪些地方会产生内存溢出?-CSDN博客 程序计数器、虚拟机栈、本地方法栈3个区域随线程而生随线程而灭栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的尽管在运行期会由即时编译器进行一些优化但在基于概念模型的讨论里大体上可以认为是编译期可知的因此这几个区域的内存分配和回收都具备确定性在这几个区域内就不需要过多考虑如何回收的问题当方法结束或者线程结束时内存自然就跟随着回收了。 那还剩下什么区域还有方法区和堆 对于方法区上面链接对应的文章中也说过方法区的内存回收目标主要是针对常量池的回收和对类型的卸载即废弃的常量和不再使用的类型但总的来说方法区的回收触发条件比较苛刻发生垃圾回收的频率比较低。举个常量池中字面量回收的例子假如一个字符串“java”曾经进入常量池中但是当前系统又没有任何一个字符串对象的值是“java”换句话说已经没有任何字符串对象引用常量池中的“java”常量且虚拟机中也没有其他地方引用这个字面量。如果在这时发生内存回收而且垃圾收集器判断确有必要的话这个“java”常量就将会被系统清理出常量池。常量池中其他类接口、方法、字段的符号引用也与此类似。 在大量使用反射、动态代理、 CGLib 等字节码框架动态生成 JSP 以及 OSGi 这类频繁自定义类加载器的场景中通常都需要Java 虚拟机具备类型卸载的能力以保证不会对方法区造成过大的内存压力。判定一个类型是否属于“不再被使用的类” 的条件就比较苛刻了。需要同时满足下面三个条件 该类所有的实例都已经被回收也就是Java堆中不存在该类及其任何派生子类的实例。 加载该类的类加载器已经被回收这个条件除非是经过精心设计的可替换类加载器的场景如OSGi、JSP的重加载等否则通常是很难达成的。 该类对应的java.lang.Class对象没有在任何地方被引用无法在任何地方通过反射访问该类的方法 垃圾回收的主要阵地是堆为什么这么说一个接口的多个实现类需要的内存可能会不一样一个方法所执行的不同条件分支所需要的内存也可能不一样只有处于运行期间我们才能知道程序究竟会创建哪些对象创建多少个对象这部分内存的分配和回收是动态的。垃圾收集器所关注的正是这部分内存该如何管理。 二、垃圾收集第一步 —— 判断对象是死是活 垃圾收集器在对堆进行回收前第一件事情就是要确定这些对象之中哪些还“ 存活 ” 着哪些已经 “ 死去 ” 不会再被使用的对象。 2.1 引用计数法 在对象中添加一个引用计数器每当有一个地方引用它时计数器值就加一当引用失效时计数器值就减一任何时刻计数器为零的对象就认为是不可能再被使用的。 原理很简单但 引用计数算法 Reference Counting虽然占用了一些额外的内存空间来进行计数最主要的它会产生决对象之间相互循环引用的问题 如下代码。这也是好多主流JVM不使用引用计数法管理内存的原因。 public static void testGC(){GC objA new GC();GC objB new GC();objA.instance objB;objB.instance objA;objA null;objB null;System.gc();} 2.2 可达分析法 这个算法的基本思路就是通过一系列称为“GC Roots” 的根对象作为起始节点集从这些节点开始根据引用关系向下搜索搜索过程所走过的路径称为“ 引用链 ” Reference Chain 如果某个对象到 GC Roots 间没有任何引用链相连或者用图论的话来说就是从GC Roots 到这个对象不可达时则证明此对象是不可能再被使用的。 对象 object 5 、 object 6 、 object 7 虽然互有关联但是它们到 GC Roots 是不可达的因此它们将会被判定为可回收的对象。 其实这种方法的关键是先确定GC Root Set即哪些对象是可以作为根对象。可以作为GC Root的对象包含 在虚拟机栈帧中的本地变量表引用的对象如各线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等。 方法区中静态属性引用的对象譬如Java类的引用类型静态变量。 方法区中常量引用的对象譬如字符串常量池String Table里的引用 本地方法栈中JNI即通常所说的Native方法引用的对象 Java虚拟机内部的引用如基本数据类型对应的Class对象一些常驻的异常对象比如NullPointExcepiton、OutOfMemoryError等还有系统类加载器。 所有被同步锁synchronized关键字持有的对象。 反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。 除了这些固定的 GC Roots 集合以外根据用户所选用的垃圾收集器以及当前回收的内存区域不同还可以有其他对象“ 临时性 ” 地加入共同构成完整 GC Roots 集合。譬如分代收集和局部回收Partial GC 如果只针对 Java 堆中某一块区域发起垃圾收集时必须考虑到内存区域是虚拟机自己的实现细节某个区域里的对象完全有可能被位于堆中其他区域的对象所引用这时候就需要将这些关联区域的对象也一并加入GC Roots 集合中去才能保证可达性分析的正确性。 2.3 引用分类 无论是通过引用计数算法判断对象的引用数量还是通过可达性分析算法判断对象是否引用链可达判定对象是否存活都和“ 引用 ” 离不开关系。在JDK 1.2版之后Java对引用的概念进行了扩充将引用分为强引用Strongly Re-ference、软 引用Soft Reference 、弱引用 Weak Reference 和虚引用 Phantom Reference 4 种这 4 种引用强度依次逐渐减弱。 强引用是最传统的“引用”的定义即类似“Object objnew Object()”这种引用关系。无论任何情况下只要强引用关系还存在垃圾收集器就永远不会回收掉被引用的对象。哪怕内存不足时JVM也会直接抛出OutOfMemoryError。软引用是用来描述一些还有用但非必须的对象。只被软引用关联着的对象在系统将要发生内存溢出异常前会把这些对象列进回收范围之中进行第二次回收如果这次回收还没有足够的内存才会抛出内存溢出异常。弱引用也是用来描述那些非必须对象但是它的强度比软引用更弱一些被弱引用关联的对象只能生存到下一次垃圾收集发生为止。当垃圾收集器开始工作无论当前内存是否足够都会回收掉只被弱引用关联的对象。 虚引用也称为 “ 幽灵引用 ” 或者 “ 幻影引用 ”它是最弱的一种引用关系。一个对象是否有虚引用的存在完全不会对其生存时间构成影响也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。如果一个对象仅持有虚引用那么它就和没有任何引用一样它随时可能会被回收在 JDK1.2 之后用 PhantomReference 类来表示通过查看这个类的源码发现它只有一个构造函数和一个 get() 方法而且它的 get() 方法仅仅是返回一个null也就是说将永远无法通过虚引用来获取对象虚引用必须要和 ReferenceQueue 引用队列一起使用。 1.强引用StrongReference 只要某个对象有强引用与之关联JVM必定不会回收这个对象即使在内存不足的情况下JVM宁愿抛出OutOfMemory错误也不会回收这种对象。比如下面这段代码 public class Main {public static void main(String[] args) {new Main().fun1();}public void fun1() {Object object new Object();Object[] objArr new Object[1000];} } 当运行至Object[] objArr new Object[1000];这句时如果内存不足JVM会抛出OOM错误也不会回收object指向的对象。不过要注意的是当fun1运行完之后object和objArr都已经不存在了所以它们指向的对象都会被JVM回收。 如果想中断强引用和某个对象之间的关联可以显示地将引用赋值为null这样一来的话JVM在合适的时间就会回收该对象。 2.软引用SoftReference 在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象只有在内存不足的时候JVM才会回收该对象。因此这一点可以很好地用来解决OOM的问题并且这个特性很适合用来实现缓存比如网页缓存、图片缓存等。下面是一个使用示例 public class Main {public static void main(String[] args) {SoftReferenceString sr new SoftReferenceString(new String(hello));System.out.println(sr.get());} } 3.弱引用WeakReference 弱引用也是用来描述非必需对象的当JVM进行垃圾回收时无论内存是否充足都会回收被弱引用关联的对象。在java中用java.lang.ref.WeakReference类来表示。下面是使用示例 public class Main {public static void main(String[] args) {WeakReferenceString sr new WeakReferenceString(new String(hello));System.out.println(sr.get());System.gc(); //通知JVM的gc进行垃圾回收System.out.println(sr.get());} } hello null 第二个输出结果是null这说明只要JVM进行垃圾回收被弱引用关联的对象必定会被回收掉。不过要注意的是这里说的被弱引用关联的对象是指只有弱引用与之关联如果存在强引用同时与之关联则垃圾回收时也不会回收该对象软引用也是如此。 4.虚引用PhantomReference 虚引用和前面的软引用、弱引用不同它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联则跟没有引用与之关联一样在任何时候都可能被垃圾回收器回收。 public class Main {public static void main(String[] args) { ReferenceQueueString queue new ReferenceQueueString();PhantomReferenceString pr new PhantomReferenceString(new String(hello), queue); System.out.println(pr.get());} } null 要注意的是虚引用必须和引用队列关联使用当垃圾回收器准备回收一个对象时如果发现它还有虚引用就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列那么就可以在所引用的对象的内存被回收之前采取必要的行动。 如何利用软引用和弱引用解决OOM问题 假如有一个应用需要读取大量的本地图片如果每次读取图片都从硬盘读取则会严重影响性能但是如果全部加载到内存当中又有可能造成内存溢出此时使用软引用可以解决这个问题。 设计思路是用一个HashMap来保存图片的路径 和 相应图片对象关联的软引用之间的映射关系在内存不足时JVM会自动回收这些缓存图片对象所占用的空间从而有效地避免了OOM的问题。在Android开发中对于大量图片下载会经常用到。 2.4 其他说明 假如一个对象被可达分析法法判定为不可达对象该对象是否就一定会被回收呢答案是否定的。 即使在可达性分析算法中判定为不可达的对象也不是 “ 非死不可 ” 的这时候它们暂时还处于 “ 缓刑” 阶段要真正宣告一个对象死亡至少要经历两次标记过程如果对象在进行可达性分析后发现没有与GC Roots 相连接的引用链那它将会被第一次标记随后进行一次筛选筛选的条件是此对象是否有必要执行finalize() 方法。假如对象没有覆盖 finalize() 方法或者 finalize() 方法已经被虚拟机调用过就不会再回收该对象 。 三、垃圾收集算法 前面说了虚拟机怎么判定一个对象是死是活的基本理论即引用计数法和可达性分析法。 垃圾收集算法基于这两种理论可以分为引用计数式垃圾收集 和 追踪式垃圾收集 两种。但是主流的虚拟机一般都属于追踪式垃圾收集因此此类型的垃圾收集器是重点。 3.1 分代收集理论 3.1.1 什么是分代 常用的垃圾收集器的一致的设计原则收集器应该将 Java 堆划分出不同的区域然后将回收对象依据其年龄年龄即对象熬过垃圾收集过程的次数分配到不同的区域之中存储。如果一个区域中大多数对象都是朝生夕灭难以熬过垃圾收集过程的话那么把它们集中放在一起每次回收时只关注如何保留少量存活而不是去标记那些大量将要被回收的对象就能以较低代价回收到大量的空间如果剩下的都是难以消亡的对象那把它们集中放在一块虚拟机便可以使用较低的频率来回收这个区域这就同时兼顾了垃圾收集的时间开销和内存的空间有效利用。 具体的可以分为 新生代收集Minor GC/Young GC指目标只是新生代的垃圾收集。 老年代收集Major GC/Old GC指目标只是老年代的垃圾收集。目前只有CMS收集器会有单独收集老年代的行为。另外请注意“Major GC”这个说法现在有点混淆在不同资料上常有不同所指需按上下文区分到底是指老年代的收集还是整堆收集。 混合收集Mixed GC指目标是收集整个新生代以及部分老年代的垃圾收集。目前只有G1收集器会有这种行为。 整堆收集Full GC收集整个Java堆和方法区的垃圾收集。 新生代Young、老年代Old是HotSpot虚拟机也是现在业界主流的命名方式 3.1.2 跨代引用 在新生代中每次垃圾收集时都发现有大批对象死去而每次回收后存活的少量对象将会逐步晋升到老年代中存放。但是实际中分代时会有跨代问题因为对象不是孤立的所以对象间会存在跨代引用。比如新生代中的对象是完全有可能被老年代所引用一旦新生代中出现了这种情况虚拟机在回收时就必须在固定的GC Root之外再额外遍历整个老年代才能最终判定某个对象的“死活”这样很显然有何分代理论相悖了说好的分代之后每个分代单独垃圾收集呢 为了解决这个矛盾出现了一个重要的法则 跨代引用相对于同代引用来说仅占极少数。存在互相引用关系的两个对象是应该倾向于同时生存或者同时消亡的。举个例子如果某个新生代对象存在跨代引用由于老年代对象难以消亡该引用会使得新生代对象在收集时同样得以存活进而在年龄增长之后晋升到老年代中这时跨代引用也随即被消除了。按照这个法则就不应再为了少量的跨代引用去扫描整个老年代也不必浪费空间专门记录每一个对象是否存在及存在哪些跨代引用只需在新生代上建立一个全局的数据结构该结构被称为“记忆集”Remembered Set这个结构把老年代划分成若干小块标识出老年代的哪一块内存会存在跨代引用。此后当发生Minor GC时只有包含了跨代引用的小块内存里的对象才会被加入到GCRoots进行扫描。虽然这种方法需要在对象改变引用关系如将自己或者某个属性赋值时维护记录数据的正确性会增加一些运行时的开销但比起收集时扫描整个老年代来说仍然是划算的。 3.1.3 分代的意义 这个分代收集理论是垃圾回收的第二个基础第一个是判断对象死活的两个方法引用计数和可达性分析它使得垃圾收集器不需要每次都针对所有的堆内存区域进行收集而只需要每次只回收其中某一个或者某些部分的区域即可提升效率和准确性。同时因为将堆内存分成了不同的年龄区域每块区域是单独收集的比如“Minor/Young GC”“Major/Old GC”“Full GC”就是分别针对年轻代、老年代及整个堆的垃圾回收那就可以对不同的代采取不同的垃圾回收算法主要有 “标记-复制算法” “标记-清除算法”“标记-整理算法”三种。   3.2  标记--清除 算法 算法分为 “ 标记 ” 和 “ 清除 ”两个阶段首先标记出所有需要回收的对象在标记完成后统一回收掉所有被标记的对象也可以反过来标记存活的对象统一回收所有未被标记的对象。标记过程就是对象“生死”的判定过程。 标记 -清除算法是最早且最基础的垃圾收集算法其他的垃圾回收算法大多以此算法为基础进行改进。说到改进那就说明这个算法是有缺陷的不然还改进干啥标记 - 清除算法主要有两个缺点 第一个是执行效率不稳定如果Java堆中包含大量对象而且其中大部分是需要被回收的这时必须进行大量标记和清除的动作导致标记和清除两个过程的执行效率都随对象数量增长而降低内存空间的碎片化问题标记、清除之后会产生大量不连续的内存碎片空间碎片太多可能会导致当以后在程序运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。 3.3  标记--复制 算法 也叫复制算法主要针对标记--清除算法面对大量可回收对象时执行效率的不足进行了改进。 标记--复制 算法将内存按容量划分为大小相等的两块每次只使用其中的一块。当其中一块的内存用完了就将还存活着的对象复制到另外一块上面然后再把已使用过的内存空间一次清理掉。 如果Java堆中包含大量对象而且其中大部分是需要被回收的标记--复制 算法只需要将少数的存活对象复制到另一块内存即可内存复制开销很小而且每次都是针对整个半区进行内存回收分配内存时也就不用考虑有空间碎片的复杂情况只要移动堆顶指针按顺序分配即可。 所以 标记--复制 算法的优点是1面对大量要回收的对象时执行效率高2没有内存碎片产生。那它有没有缺陷呢可定有啊这种复制回收算法的代价是将可用内存缩小为了原来的一半太浪费空间。其次在面对堆中有大量的对象且多数为不可回收的对象时那复制的开销就会变大。所以 标记--复制 比较适用于年轻代的垃圾收集器采用不适合老年代的垃圾收集器采用。 所以‌Serial、‌ParNewSerial、、‌Parallel Scavenge等年轻代垃圾回收期都是采用的标记-复制算法。 此外还存在”内存担保“问题这里是按1:1的比例划分内存的但实际上比如新生代中的对象有98%熬不过第一轮收集那就没必要再按这个比例来划分内存可以适当缩小保留区域的内存因为毕竟存活下来的对象不多不需要那么多内存来保存极少活下来的对象。 3.4  标记--整理 算法 标记 - 复制算法在对象存活率较高时就要进行较多的复制操作效率将会降低。更关键的是如果不想浪费50% 的空间就需要有额外的空间进行分配担保以应对被使用的内存中所有对象都 100% 存活的极端情况所以在老年代一般不能直接选用这种算法。 针对老年代对象的存亡特征诞生了“标记-整理”Mark-Compact算法其的标记过程仍然与“标记-清除”算法一样但后续步骤不是直接对可回收对象进行清理而是让所有存活的对象都向内存空间一端移动然后直接清理掉边界以外的内存。标记-清除算法与标记-整理算法的本质差异在于前者是一种非移动式的回收算法而后者是移动式的。 是否移动回收后的存活对象是一项优缺点并存的风险决策如果移动存活对象尤其是在老年代这种每次回收都有大量对象存活区域移动存活对象并更新 所有引用这些对象的地方将会是一种极为负重的操作而且这种对象移动操作必须全程暂停用户应用 程序才能进行。如果跟标记-清除算法那样完全不考虑移动和整理存活对象的话弥散于堆中的存活对象导致的 空间碎片化问题就只能依赖更为复杂的内存分配器和内存访问器来解决。 基于以上两点是否移动对象都存在弊端移动则内存回收时会更复杂不移动则内存分配时会更复杂。从垃圾收集的停顿时间来看不移动对象停顿时间会更短甚至可以不需要停顿但是从整个程序的吞吐量使用垃圾收集的用户程序或 用户线程来看移动对象会更划算。 另外还有一种 解决方案可以不在内存分配和访问上增加太大额外负担做法是让虚拟机平时多数时间都采用标记- 清除算法暂时容忍内存碎片的存在直到内存空间的碎片化程度已经大到影响对象分配时再采用标记- 整理算法收集一次以获得规整的内存空间。 四、经典垃圾回收器 垃圾收集算法是内存回收的方法论垃圾收集器就是内存回收的实践者。垃圾收集器的历史比java还要悠久因此有很多的经典的垃圾回收器但好多已经年代久远这里主要介绍两种CMSConcurrent Mark Sweep 和 G1Garbage First。 4.1 CMS收集器 Concurrent Mark Sweep翻译过来就是并发-标记-清除。这几个关键字一出想必已经知道CMS背后大致的“故事”。 CMS Concurrent Mark Sweep 收集器是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java 应用集中在互联网网站或者基于浏览器的 B/S 系统的服务端上这类应用通常都会较为关注服务的响应速度希望系统停顿时间尽可能短以给用户带来良好的交互体验。CMS收集器就非常符合这类应用的需求。CMS收集器是老年代的垃圾收集器一般情况下会有ParNew来配合执行(默认情况下也是ParNew)ParNew也是使用并行的算法来执行年轻代的回收。 CMS基于 标记--清除 算法实现整个过程分为四步 1初始标记2并发标记3重新标记4并发清除 可以看出CMS中重点是标记其中初始标记、重新标记这两个步骤仍然需要“Stop The World”也就是需要暂停所有线程那这样怎么还说CMS是响应快速的呢那是因为初始标记仅仅只是标记一下GC Root能直接关联到的对象速度很快并发标记阶段就是从GC Root的直接关联对象开始遍历整个对象图的过程这个过程虽然很耗时但却不需要停顿所有用户线程用户线程可以和垃圾收集线程一起并发运行重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录这个阶段的停顿时间通常会比初始标记阶段稍长一些但也远比并发标记阶段的时间短最后是并发清除阶段清理删除掉标记阶段判断的已经死亡的 对象由于不需要移动存活对象所以这个阶段也是可以与用户线程同时并发的。 在整个过程中耗时最长的并发标记和并发清除阶段中垃圾收集器线程都可以与用户线程一起工作所以从总体上来说CMS 收集器的内存回收过程是与用户线程一起并发执行的所以有灵敏的响应。 优缺点 优点并发收集、低停顿。 缺点1CMS收集器对处理器资源非常敏感。如果应用本来的处理器负载就很高还要分出一半的运算能力去执行收集器线程就可能导致用户程序的执行速度忽然大幅降低。2CMS是一款基于“标记-清除”算法实现的收集器收集结束时会有大量空间碎片产生。 4.2 Garbage First收集器 -- G1 G1 收集器才被 Oracle 官方称为 “ 全功能的垃圾收集器” Fully-Featured Garbage Collector 。 G1 从整体来看是基于 “ 标记 - 整理 ” 算法实现的收集器但从局部两个 Region之间上看又是基于“ 标记 - 复制 ” 算法实现。 在 G1 收集器出现之前的所有其他收集器包括CMS 在内垃圾收集的目标范围要么是整个新生代 Minor GC 要么就是整个老年代Major GC 再要么就是整个 Java 堆 Full GC 。而 G1 跳出了这个樊笼它可以面向堆内存任何部分来组成回收集Collection Set 一般简称 CSet 进行回收 衡量标准不再是它属于哪个分代而是哪块内存中存放的垃圾数量最多回收收益最大 这就是G1 收集器的 Mixed GC 模式。 G1 开创的基于 Region 的堆内存布局是它能够实现这个目标的关键。虽然 G1 也仍是遵循分代收集理论设计的但其堆内存的布局与其他收集器有非常明显的差异G1 不再坚持固定大小以及固定数量的分代区域划分而是把连续的Java 堆划分为多个大小相等的独立区域 Region 每一个 Region 都可以 根据需要扮演新生代的 Eden 空间、 Survivor 空间或者老年代空间。收集器能够对扮演不同角色的Region采用不同的策略去处理这样无论是新创建的对象还是已经存活了一段时间、熬过多次收集的旧对象都能获取很好的收集效果。 Region 中还有一类特殊的 Humongous 区域专门用来存储大对象。 G1认为只要大小超过了一个Region容量一半的对象即可判定为大对象。每个Region的大小可以通过参数-XXG1HeapRegionSize设定取值范围为1MB32MB且应为2的N次幂。而对于那些超过了整个Region容量的超级大对象将会被存放在N个连续的Humongous Region之中G1的大多数都把Humongous作为老年代的一部分来进行看待。 虽然 G1 仍然保留新生代和老年代的概念但新生代和老年代不再是固定的了。 它将Region作为单次回收的最小单元即每次收集到的内存空间都是Region大小的整数倍这样可以避免在整个Java 堆中进行全区域的垃圾收集。更具体的处理思路是让 G1 收集器去跟踪各个 Region 里面的垃圾堆积的“ 价值 ” 大小然后在后台维护一个优先级列表每次根据用户设定允许的收集停顿时间使用参数-XX MaxGCPauseMillis 指定默认值是200 毫秒优先处理回收价值收益最大的那些 Region 这也就是 “Garbage First” 名字的由来。 这种使用Region 划分内存空间以及具有优先级的区域回收方式保证了 G1 收集器在有限的时间内获取尽可能高的收集效率。 G1 收集器的运作过程大致可划分为以下四个步骤 1初始标记仅仅只是标记一下GC Roots能直接关联到的对象并且修改TAMS指针的值让下一阶段用户线程并发运行时能正确地在可用的Region中分配新对象。这个阶段需要停顿线程但耗时很短而且是借用进行Minor GC的时候同步完成的所以G1收集器在这个阶段实际并没有额外的停顿。2并发标记从GC Root开始对堆中对象进行可达性分析递归扫描整个堆里的对象图找出要回收的对象这阶段耗时较长但可与用户程序并发执行。对象图扫描完成以后还要重新处理SATB记录下的在并发时有引用变动的对象。3最终标记主要修正在并发标记阶段因为用户线程继续运行而导致标记记录产生变动的那一部分对象的标记记录。对用户线程做另一个短暂的暂停用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录。4筛选回收更新Region的统计数据对各个Region的回收价值和成本进行排序根据用户所期望的停顿时间来制定回收计划可以自由选择任意多个Region构成回收集然后把决定回收的那一部分Region的存活对象复制到空的Region中再清理掉整个旧Region的全部空间。这里的操作涉及存活对象的移动是必须暂停用户线程由多条收集器线程并行完成的。 G1 收集器除了并发标记外其余阶段也是要完全暂停用户线程的它并非纯粹地追求低延迟。上面的步骤还有需要解释的地方 TAMS和SATB。 用户线程改变对象引用关系时必须保证其不能打破原本的对象图结构导致标记结果出现错误 CMS 收集器采用增量更新算法实现而 G1收集器则是通过原始快照SATB 算法来实现的。此外垃圾收集对用户线程的影响还体现在回收过程中新创建对象的内存分配上程序要继续运行就肯定会持续有新对象被创建G1 为每一个 Region 设计了两个名为TAMS Top at Mark Start 的指针把 Region 中的一部分空间划分出来用于并发回收过程中的新对象分配并发回收时新分配的对象地址都必须要在这两个指针位置以上。G1 收集器默认在这个地址以上的对象是被隐式标记过的即默认它们是存活的不纳入回收范围。与CMS 中的“Concurrent Mode Failure” 失败会导致 Full GC 类似如果内存回收的速度赶不上内存分配的速度G1收集器也要被迫冻结用户线程执行导致 Full GC 而产生长时间 “Stop The World” 。 补充一、如何打印gc细节打印的gc日志怎么看 如何打印 public class ReferenceCountingGC {public Object instance null;private static final int _1MB 1024*1024;private byte[] bigSize new byte[2 * _1MB];public static void testGC(){ReferenceCountingGC objA new ReferenceCountingGC();ReferenceCountingGC objB new ReferenceCountingGC();objA.instance objB;objB.instance objA;objA null;objB null;System.gc();}public static void main(String[] args) {testGC();} } -XX:PrintGCDetails 打印GC前后的详细信息 -XX:PrintHeapAtGC打印GC前后的详细堆栈信息  -Xloggc:filename  (输出垃圾收集器的信息到一个指定的文件例如:-Xloggc:F://log.txt ) 怎么看 可以在启动时jvm 执行参数里面制定垃圾回收器的类型主要的垃圾回收器如下 串行收集器 DefNew是使用-XX:UseSerialGC新生代老年代都使用串行回收收集器。 并行收集器 ParNew是使用-XX:UseParNewGC新生代使用并行收集器老年代使用串行回收收集器或者-XX:UseConcMarkSweepGC(新生代使用并行收集器老年代使用CMS)。 PSYoungGen是使用-XX:UseParallelOldGC新生代老年代都使用并行回收收集器或者-XX:UseParallelGC新生代使用并行回收收集器老年代使用串行收集器 garbage-first heap是使用-XX:UseG1GCG1收集器 例如我们指定垃圾回收器是G1 补充二、如何使用JDK自带工具JConsole jconsole.exe为jdk自带的监控工具在JDK安装目录的bin文件夹下。 可以本地运行一个java程序这时上面的本地进程中会检测到你运行的程序连接后   概述 记录了“堆内存使用情况”、“线程”、“类”、“CPU使用情况”共四个资源的实时情况   内存 可以选择查看“堆内存使用情况”、“非堆内存使用情况”、“内存池PS Eden Space”等内存占用的实时情况界面右下角还有图形化的堆一级、二级、三级缓存从左到右占用情况当然如果三级缓存被全部占用也就是很可能内存溢出啦这时可以去查看服务器的tomcat日志应该会有“outofmemory的异常日志信息。界面右上角处还提供了一个“执行GC”的手动垃圾收集功能这个也很实用~而且界面下方还有详细的GC信息记录。   线程 界面上部显示实时线程数目。下部还能查看到详细的每个进程及相应状态、等待、堆栈追踪等信息   类 显示“已装入类的数目”、“已卸载类的数目”信息   VM概要 显示服务器详细资源信息包括线程、类、OS、内存等   MBean : 可在此页进行参数的配置。 补充三、JVM调优经验 1、首先考虑GC策略不合适的GC策略会影响效率。在jvm执行参数中选择合适的垃圾收集器 2、其次考虑内存设置虽然现在线上业务系统基本物理内存都是够用的不过物尽其用调优就是争取让每M空间都发挥出最大的作用。内存的设置还是最直观见效的。 -Xmx500m ,-Xms500m 最大堆内存和最小堆内存这两个值要设的一致避免虚拟机还要动态计算分配内存空间。 PS堆也不是越大越好堆太大带来的后果就是单次GC会较长。 -Xmn250m 新生代大小非G1收集器可以设置这个值G1的官方建议是不要显示分配新生代和老年代空间大小因为G1会通过网格化内存来动态分配new/old区官方认为不设置new size是最佳实践。 -Xss2m 每个线程的栈空间大小默认值是1m一般不需要设置除非有递归方法存在可能会爆栈。 JDK8之后取消了永久代改为元空间(MetaSpace)这块属于本地内存理论上可以利用系统剩余的所有内存不过跑了多个实例的话还是要设置一下为妙 -XX:MetaspaceSize128m,-XX:MaxMetaspaceSize256m -XX:MaxDirectMemorySize128m 这个属于堆外内存可以合理控制大小。Heap区总内存减去一个Survivor区的大小,不宜过大否则可能heap size Direct Memory Size把物理内存耗光。 -XX:SurvivorRatio7 默认是8新生代中Eden与Survivor的比值过大的话可能Survivor存不下临时对象而频繁触发分配担保。可以根据GC日志看实际情况。 3、监控输出 监控参数还是需要的线上偶尔OOM了时快速定位解决。 -XX:HeapDumpOnOutOfMemoryError,-XX:HeapDumpPath{path} OOM的时候会输出dump快照到{path}目录只需要指向目录文件名JVM会保持唯一性。 -XX:PrintGCDetails,-Xloggc:logs/gc.log,-XX:PrintGCTimeStamps,-XX:PrintGCDateStamps 打印GC详细记录。
文章转载自:
http://www.morning.xpqsk.cn.gov.cn.xpqsk.cn
http://www.morning.lgtzd.cn.gov.cn.lgtzd.cn
http://www.morning.frllr.cn.gov.cn.frllr.cn
http://www.morning.kwwkm.cn.gov.cn.kwwkm.cn
http://www.morning.rgqnt.cn.gov.cn.rgqnt.cn
http://www.morning.mbmh.cn.gov.cn.mbmh.cn
http://www.morning.sgmgz.cn.gov.cn.sgmgz.cn
http://www.morning.qyfqx.cn.gov.cn.qyfqx.cn
http://www.morning.lkbyj.cn.gov.cn.lkbyj.cn
http://www.morning.zlgr.cn.gov.cn.zlgr.cn
http://www.morning.tktcr.cn.gov.cn.tktcr.cn
http://www.morning.lphtm.cn.gov.cn.lphtm.cn
http://www.morning.nqfxq.cn.gov.cn.nqfxq.cn
http://www.morning.ktcrr.cn.gov.cn.ktcrr.cn
http://www.morning.jfbgn.cn.gov.cn.jfbgn.cn
http://www.morning.shnqh.cn.gov.cn.shnqh.cn
http://www.morning.hbtarq.com.gov.cn.hbtarq.com
http://www.morning.bwjws.cn.gov.cn.bwjws.cn
http://www.morning.ychoise.com.gov.cn.ychoise.com
http://www.morning.bdfph.cn.gov.cn.bdfph.cn
http://www.morning.fpxyy.cn.gov.cn.fpxyy.cn
http://www.morning.hkcjx.cn.gov.cn.hkcjx.cn
http://www.morning.psdsk.cn.gov.cn.psdsk.cn
http://www.morning.zplzj.cn.gov.cn.zplzj.cn
http://www.morning.zwhtr.cn.gov.cn.zwhtr.cn
http://www.morning.tbksk.cn.gov.cn.tbksk.cn
http://www.morning.ypqwm.cn.gov.cn.ypqwm.cn
http://www.morning.nyhtf.cn.gov.cn.nyhtf.cn
http://www.morning.ztfzm.cn.gov.cn.ztfzm.cn
http://www.morning.hrzymy.com.gov.cn.hrzymy.com
http://www.morning.nuejun.com.gov.cn.nuejun.com
http://www.morning.nrmyj.cn.gov.cn.nrmyj.cn
http://www.morning.nckjk.cn.gov.cn.nckjk.cn
http://www.morning.yxlpj.cn.gov.cn.yxlpj.cn
http://www.morning.ssmhn.cn.gov.cn.ssmhn.cn
http://www.morning.zymgs.cn.gov.cn.zymgs.cn
http://www.morning.zsthg.cn.gov.cn.zsthg.cn
http://www.morning.njstzsh.com.gov.cn.njstzsh.com
http://www.morning.qfwfj.cn.gov.cn.qfwfj.cn
http://www.morning.qytpt.cn.gov.cn.qytpt.cn
http://www.morning.lpmdy.cn.gov.cn.lpmdy.cn
http://www.morning.lcxzg.cn.gov.cn.lcxzg.cn
http://www.morning.ktrh.cn.gov.cn.ktrh.cn
http://www.morning.yxbdl.cn.gov.cn.yxbdl.cn
http://www.morning.mwnch.cn.gov.cn.mwnch.cn
http://www.morning.lpmjr.cn.gov.cn.lpmjr.cn
http://www.morning.dycbp.cn.gov.cn.dycbp.cn
http://www.morning.rxydr.cn.gov.cn.rxydr.cn
http://www.morning.mqzcn.cn.gov.cn.mqzcn.cn
http://www.morning.hnhkz.cn.gov.cn.hnhkz.cn
http://www.morning.ybgcn.cn.gov.cn.ybgcn.cn
http://www.morning.jzyfy.cn.gov.cn.jzyfy.cn
http://www.morning.znlhc.cn.gov.cn.znlhc.cn
http://www.morning.jzsgn.cn.gov.cn.jzsgn.cn
http://www.morning.mkhwx.cn.gov.cn.mkhwx.cn
http://www.morning.mlbn.cn.gov.cn.mlbn.cn
http://www.morning.rqwmt.cn.gov.cn.rqwmt.cn
http://www.morning.qgkcs.cn.gov.cn.qgkcs.cn
http://www.morning.lgtcg.cn.gov.cn.lgtcg.cn
http://www.morning.tqbw.cn.gov.cn.tqbw.cn
http://www.morning.wsgyq.cn.gov.cn.wsgyq.cn
http://www.morning.nfccq.cn.gov.cn.nfccq.cn
http://www.morning.rzbcz.cn.gov.cn.rzbcz.cn
http://www.morning.gsqw.cn.gov.cn.gsqw.cn
http://www.morning.dxqwm.cn.gov.cn.dxqwm.cn
http://www.morning.qhnmj.cn.gov.cn.qhnmj.cn
http://www.morning.fnmtc.cn.gov.cn.fnmtc.cn
http://www.morning.bwzzt.cn.gov.cn.bwzzt.cn
http://www.morning.fcpjq.cn.gov.cn.fcpjq.cn
http://www.morning.xbdrc.cn.gov.cn.xbdrc.cn
http://www.morning.xdwcg.cn.gov.cn.xdwcg.cn
http://www.morning.wqkfm.cn.gov.cn.wqkfm.cn
http://www.morning.lgnrl.cn.gov.cn.lgnrl.cn
http://www.morning.dbsch.cn.gov.cn.dbsch.cn
http://www.morning.dtzsm.cn.gov.cn.dtzsm.cn
http://www.morning.gqksd.cn.gov.cn.gqksd.cn
http://www.morning.nlpbh.cn.gov.cn.nlpbh.cn
http://www.morning.kztts.cn.gov.cn.kztts.cn
http://www.morning.khpx.cn.gov.cn.khpx.cn
http://www.morning.psxxp.cn.gov.cn.psxxp.cn
http://www.tj-hxxt.cn/news/255891.html

相关文章:

  • 织梦做的网站网速打开慢是怎么回事河南推广网站
  • wordpress网站采集插件免费推广的渠道有哪些
  • 镭拓网站建设哪些网站做舆情分析
  • 校园网站开发的需求分析网站后台账号密码忘记了怎么办
  • easyui 做的网站找人做网站多少钱
  • 门户网站建设依据好用的手机网站主页
  • 杭州群游科技网站做的魔域全国培训机构排名前十
  • 网站建设全流程图这么做网站
  • 仿站工具箱网站建设开票开什么内容
  • 网站策划运营方案书wordpress免费 主题
  • 成都优化网站厂家开发购物平台网站费用
  • 网站栏目内容和功能网站域名注销电话
  • 东阳科技网站建设网站解析时候让做别名
  • 做购物平台网站 民治wordpress转播
  • vscode的网站开发配置wordpress 目录404
  • vps建立多个网站大型网站快速排名
  • 怎么搭建自己公司网站免费的ppt制作软件
  • 海报在线设计网站广告网上接单
  • 中国建设银行复核网站开发助手
  • 马鞍山市网站建设wordpress换主题影响seo吗
  • 柳州市建设工程质量安全监督管理处网站大连甘井子区地图
  • 网页制作公司兼职seo外包服务费用
  • 网站建设公司需要哪些网站流量指标有哪些
  • 做企业网站时需要注意哪些地方台州网站制作教程
  • 如何做网络营销推广就属金手指饣自己的网站怎么做关键词优化
  • 北京海淀网站制作温州seo招聘
  • 国外做蛋糕的网站聊天网站站怎么做
  • 网站转化率低免费素材网站素材库
  • 免费国外ddos网站一诺建站
  • html5网站设计wordpress页面连接