zoukankan      html  css  js  c++  java
  • 《java虚拟机》----垃圾收集、内存分配

    No1:

    程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭:栈中的栈帧随着方法的进入和退出而有条不紊的执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上市在类结构确定下来时就已知的,因此这几个区域的内存分配和回收都具备确定性,在这几个区域内就不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了。

    而java堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,我们只有在程序处于运行期间才能知道会创建哪些对象,这部分内存的分配和回收都是动态的,垃圾收集器所关注的是这部分内存。

    No2:

    引用计数算法:给对象中添加一个引用计数器,当有一个地方引用它时,计数器就+1,当引用失效,则-1,任何时刻计数器为0的对象就是不可能再被使用的。

    No3:

    可达性分析算法:基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

    在java语言中,可作为GC Roots的对象包括下面几种:

    1.虚拟机栈(栈帧中的本地变量表)中引用的对象

    2.方法区中类静态属性引用的对象

    3.方法区中常量引用的对象

    4.本地方法中JNI引用的对象

    No4:

    1.强引用就是指在程序代码中普遍存在的,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象

    2.软引用描述一些还有用但并非必需的对象。在系统将要发生内存溢出出异常之前,将会把这些对象列进回收范围之中进行第二次回收。

    3.弱引用也是描述非必需对象。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象

    4.为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

    No5:

    可达性分析算法

    第一次收集:当对象可达性分析后发现没有与GC Roots相连,则进行第一次筛选:没有复写finalize()方法或已经调用过finalize()方法,则进行标记为没有必要执行;如果判定为有必要执行finalize()方法,则对象将被放置在一个F-Queue队列中

    第二次收集:只要对象在finalize()中重新与引用链上任何一个对象建立关联即可移除“即将回收”的集合,如果没有逃脱,基本就真的被回收了

    No6:

    在堆中,新生代进行一次垃圾收集一般可回收70%~95%的空间,而永久代的垃圾收集效率远低于此。

    永久代的垃圾收集主要回收两部分内容:废弃常量和无用的类。

    No7:

    类需要同时满足下面3个条件才能算是“无用的类”:

    1.该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例

    2.加载该类的ClassLoader已经被回收

    3.该类对应的java.lang.Class对象没有在任何地方被引用,无法再任何地方通过反射访问该类的方法

    No8:

    垃圾收集算法:标记-清除算法

    两个不足:

    1.效率问题。标记和清除两个过程的效率都不高

    2.空间问题。标记清除猴会产生大量不连续的内存碎片,空间碎片太多可能会导致需要分配大对象时,无法找到足够的连续内存而不得不提前出发一次垃圾收集动作

    No9:

    垃圾收集算法:复制算法(为了解决效率而生)

    将内存分为大小相等的两块,每次只用其中一块,当其中一块用完,就将存活对象复制到另外一块上面,然后将原内存空间一次清理掉。代价是内存缩小为原来的一半,另外较多的复制也会将效率变低

    所以此算法常用来回收新生代

    No10:

    垃圾收集算法:标记-整理算法

    标记过程和标记-清除算法一样,但后续步骤是让所有存活对象向一端移动,然后直接清理掉端边界以外的内存

    此算法常用来回收老年代

    No11:

    分代收集算法:新生代选用复制算法,老年代选用标记-清除或标记-整理算法

    No12:

    安全点设置:

    1.抢先式中断:GC发生时,先中断所有线程,发现有线程不在安全点上,就恢复跑到安全点。这种方式已经不用了

    2.主动式中断:仅仅简单设置一个标志,各个线程执行时主动轮询这个标志,发现标志为真就自己中断挂起,轮询标志地方和安全点是重合的。

    No13:

    安全区域是指在一段代码片段之中,引用关系不会发生变化。在这个区域中的任意地方开始GC都是安全的。

    No14:

    收集器:Serial收集器(单线程收集器)

    特点:简单而高效

    常用来回收新生代,收集几十兆甚至一两百兆的新生代,停顿时间完全可控制在十几毫秒最多一百多毫秒以内。

    No15:

    收集器:ParNew收集器(Serial的多线程版本)

    新生代首选收集器

    No16:

    并行(Parallel):多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态

    并发(Concurrent):用户线程与垃圾收集线程同时执行(不一定是并行的,可能会交替执行),用户程序在继续运行,而垃圾收集程序运行于另一个CPU上。

    No17:

    收集器:Parrel Scavenge收集器(新生代收集器,使用复制算法,并行多线程)

    它的目标是达到一个可控制的吞吐量(吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间))

    高吞吐量可以高效率的利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务

    虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量,这种调节方式称为GC自适应的调节策略。自适应调节策略也是Parallel Scavenge收集器与ParNew收集器的一个重要区别。

    No18:

    收集器:Serial Old是Serial收集器的老年代版本(单线程,使用标记-整理算法)

    No19:

    收集器:Parallel Old收集器(Parallel Scavenge收集器的老年代版本,多线程、使用标记整理算法)

    No20:

    收集器:CMS收集器(标记-清除算法)

    是一种以获取最短回收停顿时间为目标的收集器

    步骤:

    1.初始标记  仅仅标记GC Roots能直接关联到的对象

    2.并发标记  进行GC Roots Tracing的过程(耗时最长)

    3.重新标记  修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录

    4.并发清除  

    优点:并发低停顿

    缺点:1.当CPU不足4个时,CMS会占用一半的运算能力去执行收集器线程,导致用户程序的执行速度忽然降低了50%

    2.无法处理浮动垃圾,可能出现Concurrent Mode Failure(并发模式失败)失败而导致另一次Full GC的产生,这样停顿的时间就很长了

    浮动垃圾:CMS并发清理阶段用户线程还在运行着,伴随程序运行自然就会有新的垃圾不断产生,这部分垃圾出现在标记过程之后,CMS无法在当次收集处理掉他们,只好留待下一次GC时再清理掉。

    3.当空间碎片太多而提前触发Full GC时,停顿时间也会变长

    No21:

    收集器:G1收集器

    特点:

    1.并发与并行  充分利用CPU、多核环境下的硬件优势,使用多个CPU来缩短Stop-The-World停顿的时间

    2.分代收集  

    3.空间整合  整体上基于标记-整理算法,局部(两个Region之间)基于复制算法

    4.可预测的停顿  建立可预测的停顿时间模型,能明确指定在长度为M毫秒的时间片段内,垃圾收集消耗时间不得超过N毫秒

    运作步骤  1.初始标记  2.并发标记  3.最终标记  4.筛选回收

    每个Region都有一个与之对应的Remembered Set,类似对象引用的标示符,为了避免全堆扫描

    No22:

    新生代GC(Minor GC):发生在新生代的垃圾收集动作,因为java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快

    老年代GC(Major GC/Full GC):发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程),Major GC的速度一般会比Minor GC慢10倍以上

    No23:

    内存分配和回收策略

    1.对象优先在新生代Eden区中分配:当Eden区没有足够空间时,虚拟机将发起一次Minor GC

    2.大对象直接进入老年代(最典型的大对象就是那种很长的字符串以及数组)

    3.长期存活的对象将进入老年代:对象在Survivor区中没熬过一次Minor GC,年龄就增加1岁,当年龄增加到默认15岁时晋升为老年代

    4.动态对象年龄判定:如果Survivor空间中相同年龄所有对象大小总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代

    5.空间分配担保:当出现大量对象在Minor GC后仍然存活的情况,就需要老年代进行分配担保,把Survivor无法容纳的对象直接进入老年代,否则将尝试进行一次Full GC;(因为新生代使用复制收集算法)

    101

  • 相关阅读:
    清除div中内容
    jq选中问题
    ios 笔记
    ios学习笔记01
    checkbox判断选中
    滚动条
    tooltip
    页面跳转的问题
    freemark 判断是否为空 是否存在
    构造析构与虚函数
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/7513980.html
Copyright © 2011-2022 走看看