有没有专做于投融资的网站,粉色大气妇科医院网站源码,wordpress 微信 权限,关于网站建设的新闻一#xff1a;什么是垃圾回收机制#xff08;GC#xff09;
在C/C程序中#xff0c;程序员在内存中主动开辟一段相应的空间来存值。由于内存是有限的#xff0c;所以当程序不再需要使用该内存空间时#xff0c;就需要销毁对象并释放其所占用的内存资源#xff0c;好重新…一什么是垃圾回收机制GC
在C/C程序中程序员在内存中主动开辟一段相应的空间来存值。由于内存是有限的所以当程序不再需要使用该内存空间时就需要销毁对象并释放其所占用的内存资源好重新利用这段空间。在C/C中释放无用内存空间的事情需要由程序员自己来处理。就是说当程序员认为空间没用了就手动地释放其占用的内存。但是这样显然非常繁琐如果有所遗漏就可能造成资源浪费甚至内存泄露。当软件系统比较复杂变量多的时候程序员往往就忘记释放内存或者在不该释放的时候释放内存了。 有了GC程序员就不需要再手动的去控制内存的释放。当Java虚拟机VM或.NETCLR发觉内存资源紧张的时候就会自动地去清理无用对象没有被引用到的对象所占用的内存空间
二:需要GC的内存区域
jvm 中程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭栈帧随着方法的进入和退出做入栈和出栈操作实现了自动的内存清理因此我们的内存垃圾回收主要集中于 java 堆和方法区中在程序运行期间这部分内存的分配和使用都是动态的。
三:如何判断一个对象是否存活死的话就回收
(1引用计数
每个对象有一个引用计数属性新增一个引用时计数加1引用释放时计数减1计数为0时可以回收。此方法简单无法解决对象相互循环引用的问题。
2可达性分析Reachability Analysis
从GC Roots开始向下搜索搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时则证明此对象是不可用的。不可达对象。
3:java中可作为GC Root的对象有
1.虚拟机栈中引用的对象本地变量表 2.方法区中静态属性引用的对象 3. 方法区中常量引用的对象 4.本地方法栈中引用的对象Native对象
四:何时触发GC
程序调用System.gc时可以触发系统自身来决定GC触发的时机(Young GCOld GCFULL GC ,Mixed GC)Young GC: 新生代内存的垃圾收集事件称为 Young GC又称 Minor GC当 JVM 无法为新对象分配在新生代内存空间时总会触发 Young GC。比如 Eden 区占满时新对象分配频率越高Young GC 的频率就越高。Young GC 每次都会引起全线停顿Stop-The-World暂停所有的应用线程停顿时间相对老年代 GC 造成的停顿几乎可以忽略不计。Old GC只清理老年代空间的 GC 事件只有 CMS 的并发收集是这个模式Full GC清理整个堆的 GC 事件包括新生代、老年代、元空间等Mixed GC清理整个新生代以及部分老年代的 GC只有 G1 有这个模式。
五:GC做了什么事情
主要做了清理对象整理内存的工作。Java堆分为新生代和老年代采用了不同的回收方式。
六:GC常用的算法
1:简介
GC常用算法有标记-清除算法标记-压缩算法复制算法分代收集算法。 目前主流的JVMHotSpot采用的是分代收集算法。
2.标记-清除算法:
a.标记-清除算法: 为每个对象存储一个标记位记录对象的状态活着或是死亡。分为两个阶段一个是标记阶段这个阶段内为每个对象更新标记位检查对象是否死亡第二个阶段是清除阶段该阶段对死亡的对象进行清除执行 GC 操作。优点: 最大的优点是标记—清除算法中每个活着的对象的引用只需要找到一个即可找到一个就可以判断它为活的。此外更重要的是这个算法并不移动对象的位置。缺点: 它的缺点就是效率比较低递归与全堆对象遍历。每个活着的对象都要在标记阶段遍历一遍所有对象都要在清除阶段扫描一遍因此算法复杂度较高。没有移动对象导致可能出现很多碎片空间无法利用的情况。
3:复制算法:
b.复制算法: 该算法将内存平均分成两部分然后每次只使用其中的一部分当这部分内存满的时候将内存中所有存活的对象复制到另一个内存中然后将之前的内存清空只使用这部分内存循环下去。 注意 这个算法与标记-整理算法的区别在于该算法不是在同一个区域复制而是将所有存活的对象复制到另一个区域内。优点: 实现简单不产生内存碎片缺点: 每次运行总有一半内存是空的导致可使用的内存空间只有原来的一半。(内存利用率不高)
4:标记整理算法
为了解决Copying算法的缺陷充分利用内存空间提出了Mark-Compact算法。该算法标记阶段和Mark-Sweep一样但是在完成标记之后它不是直接清理可回收对象而是将存活对象都向一端移动然后清理掉端边界以外的内存。
5:分代收集算法:
现在的虚拟机垃圾收集大多采用这种方式它根据对象的生存周期将堆分为新生代(Young)和老年代(Tenure)。 在新生代中由于对象生存期短每次回收都会有大量对象死去那么这时就采用复制算法。 老年代里的对象存活率较高没有额外的空间进行分配担保所以可以使用标记-整理 或者 标记-清除。一般将占用内存较大的对象存放在老年代的内存中 具体过程新生代(Young)分为Eden区From区与To区也就是survive 当系统创建一个对象的时候总是在Eden区操作当这个区满了那么就会触发一次YoungGC也就是年轻代的垃圾回收。一般来说这时候不是所有的对象都没用了所以就会把还能用的对象复制到From区。 这样整个Eden区就被清理干净了可以继续创建新的对象当Eden区再次被用完就再触发一次YoungGC然后呢注意这个时候跟刚才稍稍有点区别。这次触发YoungGC后会将Eden区与From区还在被使用的对象复制到To区。 下一次YoungGC的时候则是将Eden区与To区中的还在被使用的对象复制到From区。 经过若干次YoungGC后有些对象在From与To之间来回游荡这时候From区与To区亮出了底线阈值这些家伙要是到现在还没挂掉对不起一起滚到复制老年代吧。老年代经过这么几次折腾也就扛不住了空间被用完好那就来次集体大扫除Full GC也就是全量回收。如果Full GC使用太频繁的话无疑会对系统性能产生很大的影响。所以要合理设置年轻代与老年代的大小尽量减少Full GC的操作。
七:垃圾回收器
1:概览
垃圾回收器一般是分为年轻代何老年代的 需要搭配使用 如果说收集算法是内存回收的方法论垃圾收集器就是内存回收的具体实现
2:Serial收集器
串行收集器是最古老最稳定以及效率高的收集器 可能会产生较长的停顿(stop-the-world应用线程终止 启动GC线程)只使用一个线程去回收 -XX:UseSerialGC 新生代、老年代使用串行回收 新生代复制算法 老年代标记-压缩
3:ParNew并行收集器
解决Serival单个线程回收效率低下的弊端,从而使用多线程 -XX:UseParNewGCnew代表新生代所以适用于新生代 新生代并行 老年代串行 Serial收集器新生代的并行版本 在新生代回收时使用复制算法 多线程需要多核支持 -XX:ParallelGCThreads 限制线程数量
4.Parallel收集器
Parallel收集器 和ParNew收集器类似是一个新生代收集器。使用复制算法的并行多线程收集器。 该垃圾收集器是JAVA虚拟机在Server模式下的默认值使用Server模式后Java虚拟机使用Parallel Scavenge收集器新生代 Serial Old收集器老年代的收集器组合进行内存回收。 该收集器还有个特点就是“吞吐量优先”JVM自动调节参数已达到预设的吞吐量提升性能。
5:Parallel Old 收集器
老年代收集器,Parallel Old是Parallel Scavenge收集器的老年代版本使用多线程和“标记整理”算法。这个收集器是在JDK 1.6中才开始提供的在此之前新生代的Parallel Scavenge收集器一直处于比较尴尬的状态。原因是如果新生代选择了Parallel Scavenge收集器老年代除了Serial OldPS MarkSweep收集器外别无选择还记得上面说过Parallel Scavenge收集器无法与CMS收集器配合工作吗。由于老年代Serial Old收集器在服务端应用性能上的“拖累”使用了Parallel Scavenge收集器也未必能在整体应用上获得吞吐量最大化的效果由于单线程的老年代收集中无法充分利用服务器多CPU的处理能力。直到Parallel Old收集器出现后“吞吐量优先”收集器终于有了比较名副其实的应用组合在注重吞吐量以及CPU资源敏感的场合都可以优先考虑Parallel Scavenge加Parallel Old收集器。
6:CMS收集器老年代收集器
1简介
Concurrent Mark Sweep 并发标记清除应用程序线程和GC线程交替执行 使用标记-清除算法 并发阶段会降低吞吐量停顿时间减少吞吐量降低 老年代收集器新生代使用ParNew -XX:UseConcMarkSweepGC 老年代收集器它的主要适合场景是对响应时间的重要性需求 大于对吞吐量的要求能够承受垃圾回收线程和应用线程共享处理器资源并且应用中存在比较多的长生命周期的对象的应用。CMS是用于对tenured generation的回收也就是年老代的回收目标是尽量减少应用的暂停时间减少full gc发生的几率利用和应用程序线程并发的垃圾回收线程来标记清除年老代。在我们的应用中因为有缓存的存在并且对于响应时间也有比较高的要求因此希 望能尝试使用CMS来替代默认的server型JVM使用的并行收集器以便获得更短的垃圾回收的暂停时间提高程序的响应性。
(2):CMS的运行过程
1.初始标记会产生全局停顿 根可以直接关联到的对象 速度快 并发标记和用户线程一起 主要标记过程标记全部对象 重新标记 会产生全局停顿 由于并发标记时用户线程依然运行因此在正式清理前再做修正 并发清除和用户线程一起 基于标记结果直接清理对象 这里就能很明显的看出为什么CMS要使用标记清除而不是标记压缩如果使用标记压缩需要多对象的内存位置进行改变这样程序就很难继续执行。但是标记清除会产生大量内存碎片不利于内存分配。
(3):CMS收集器特点
a:尽可能降低停顿会影响系统整体吞吐量和性能 比如在用户线程运行过程中分一半CPU去做GC系统性能在GC阶段反应速度就下降一半b:清理不彻底 因为在清理阶段用户线程还在运行会产生新的垃圾无法清理c:CMS也提供了整理碎片的参数 设置进行几次Full GC后进行一次碎片整理,整理过程是独占的会引起停顿时间变长总结 CMS的提出是想改善GC的停顿时间在GC过程中的确做到了减少GC时间但是同样导致产生大量内存碎片又需要消耗大量时间去整理碎片从本质上并没有改善时间。
7:G1收集器
(1):简介
G1Garbage-First是一款面向服务器的垃圾收集器支持新生代和老年代空间的垃圾收集主要针对配备多核处理器及大容量内存的机器。与CMS收集器相比G1收集器有以下特点 (1) 空间整合G1收集器采用标记-整理算法不会产生内存空间碎片。分配大对象时不会因为无法找到连续空间而提前触发下一次GC。 (2)可预测停顿这是G1的另一大优势降低停顿时间是G1和CMS的共同关注点但G1除了追求低停顿外还能建立可预测的停顿时间模型能让使用者明确指定在一个长度为N毫秒的时间片段内消耗在垃圾收集上的时间不得超过N毫秒这几乎已经是实时JavaRTSJ的垃圾收集器的特征了。G1 堆空间划分Region 为实现大内存空间的低停顿时间的回收将划分为多个大小相等的 Region。每个小堆区都可能是 Eden 区Survivor 区或者 Old 区但是在同一时刻只能属于某个代 在逻辑上, 所有的 Eden 区和 Survivor 区合起来就是新生代所有的 Old 区合起来就是老年代且新生代和老年代各自的内存 Region 区域由 G1 自动控制不断变动。G1 把堆内存划分成一个个 Region 的意义在于 每次 GC 不必都去处理整个堆空间而是每次只处理一部分 Region实现大容量内存的 GC。 通过计算每个 Region 的回收价值包括回收所需时间、可回收空间在有限时间内尽可能回收更多的垃圾对象把垃圾回收造成的停顿时间控制在预期配置的时间范围内这也是 G1 名称的由来Garbage-First
(2):G1的几个阶段
初始标记(会有stw) 并发标记 最终标记 筛选回收
(3):相对于CMS的区别在
G1在压缩空间方面有优势G1通过将内存空间分成区域Region的方式避免内存碎片问题Eden, Survivor, Old区不再固定、在内存使用效率上来说更灵活G1可以通过设置预期停顿时间Pause Time来控制垃圾收集时间避免应用雪崩现象G1在回收内存后会马上同时做合并空闲内存的工作、而CMS默认是在STWstop the world的时候做G1也会在Young GC中使用、而CMS只能在Old GC区使用