精华内容
下载资源
问答
  • 1.收集器概览   Oracle Hotspot JVM中实现了多种垃圾收集器,针对不同的年龄代内存中的对象的生存周期和应用程序的特点,实现了多款垃圾收集器。   单线程GC收集器包括Serial和SerialOld这两款收集器,分别用于...


    1.年轻代收集器

      年轻代收集器包括Serial收集器、ParNew收集器以及Parallel Scavenge收集器。

    1.1 Serial收集器

      Serial收集器是一款年轻代的垃圾收集器,使用复制算法。它是一款发展历史最悠久的垃圾收集器。Serial收集器只能使用一条线程进行垃圾收集工作,在串行处理器中minor和major GC过程都是用一个线程进行回收的。它的最大特点是在进行垃圾回收时,需要对所有正在执行的线程暂停STW(stop the world —— 在进行垃圾收集的时候,所有的工作线程都需要停止工作,等待垃圾收集线程完成以后,其他线程才可以继续工作),几十毫秒的停顿对于大多数应用还是可以接受的,该收集器适用于单CPU、新生代空间较小且对暂停时间要求不是特别高的应用上,是client级别的默认GC方式。工作过程可以简单的用下图来表示:

    Serial收集器

      从图中可以看到,Serial收集器工作的时候,其他用户线程都停止下来,等到GC过程结束以后,它们才继续执行。而且处理GC过程的只有一条线程在执行。由于Serial收集器的这种工作机制,所以在进行垃圾收集过程中,会出现STW(Stop The World)的情况,应用程序会出现停顿的状况。如果垃圾收集的时间很长,那么停顿时间也会很长,这样会导致系统响应变的迟钝,影响系统的时候。

      虽然这款年迈的垃圾收集器只能使用单核CPU,但是正是由于它不能利用多核,在一些场景下,减少了很多线程的上下文切换的开销,可以在进行垃圾收集过程中专心处理GC过程,而不会被打断,所以如果GC过程很短暂,那么这款收集器还是非常简单高效的。

      由于Serial收集器只能使用单核CPU,在现代处理器基本都是多核多线程的情况下,为了充分利用多核的优势,出现了多线程版本的垃圾收集器,比如下面将要说到的ParNew收集器。

    1.2 ParNew收集器

      ParNew垃圾收集器是Serial收集器的多线程版本,提高了效率,这样它就可以被用于服务端上(server),同时它可以与CMS GC配合,所以,更加有理由将他用于server端。其使用复制算法。为了利用CPU多核多线程的优势,ParNew收集器可以运行多个收集线程来进行垃圾收集工作。这样可以提高垃圾收集过程的效率。

    ParNew收集器

      和上面的Serial收集器比较,可以明显看到,在垃圾收集过程中,GC线程是多线程执行的,而在Serial收集器中,只有一个GC线程在处理垃圾收集过程。ParNew收集器在很多时候都是作为服务端的年轻代收集器的选择,除了它具有比Serial收集器更好的性能外,还有一个原因是,多线程版本的年轻代收集器中,只有它可以和CMS这款优秀的老年代收集器一起搭配搭配使用。

      作为一款多线程收集器,当它运行在单CPU的机器上的时候,由于不能利用多核的优势,在线程收集过程中可能会出现频繁上下文切换,导致额外的开销,所以在单CPU的机器上,ParNew收集器的性能不一定好于Serial这款单线程收集器。如果机器是多CPU的,那么ParNew还是可以很好的提高GC收集的效率的。

      ParNew收集器默认开启的垃圾收集线程数是和当前机器的CPU数量相同的,为了控制GC收集线程的数量,可以通过参数-XX:ParallelGCThreads来控制垃圾收集线程的数量。

    1.3 Parallel Scavenge收集器

      Parallel Scavenge收集器是是一款年轻代的收集器,它使用复制算法,在整个扫描和复制过程采用多线程的方式进行,适用于多CPU、对暂停时间要求较短的应用,是server级别的默认GC方式。和ParNew一样,它也会一款多线程的垃圾收集器,但是它又和ParNew有很大的不同点。

      Parallel Scavenge收集器和其他收集器的关注点不同。其他收集器,比如ParNew和CMS这些收集器,它们主要关注的是如何缩短垃圾收集的时间。而Parallel Scavenge收集器关注的是如何控制系统运行的吞吐量。这里说的吞吐量,指的是CPU用于运行应用程序的时间和CPU总时间的占比,吞吐量 = 代码运行时间 / (代码运行时间 + 垃圾收集时间)。如果虚拟机运行的总的CPU时间是100分钟,而用于执行垃圾收集的时间为1分钟,那么吞吐量就是99%。

    Parallel Scavenge收集器

      直观上,好像以缩短垃圾收集的停顿时间为目的和以控制吞吐量为目的差不多,但是适用的场景却不同。对于那些桌面应用程序,为了得到良好的用户体验,在交互过程中,需要得到快速的响应,所以系统的停顿时间要尽可能的快以避免影响到系统的响应速度,只要保证每次停顿的时间很短暂,假设每次停顿时间为10ms,那么即使发生很多次的垃圾收集过程,假设1000次,也不会影响到系统的响应速度,不会影响到用户的体验。对于一些后台计算任务,它不需要和用户进行交互,所以短暂的停顿时间对它而言并不需要,对于计算任务而言,更好的利用CPU时间,提高计算效率才是需要的,所以假设每次停顿时间相对很长,有100ms,而由于花费了很长的时间进行垃圾收集,那么垃圾收集的次数就会降下来,假设只有5次,那么显然,使用以吞吐量为目的的垃圾收集器,可以更加有效的利用CPU来完成计算任务。所以,在用户界面程序中,使用低延迟的垃圾收集器会有很好的效果,而对于后台计算任务的系统,高吞吐量的收集器才是首选。

      Parallel Scavenge收集器提供了两个参数用于控制吞吐量。-XX:MaxGCPauseMillis用于控制最大垃圾收集停顿时间,-XX:GCTimeRatio用于直接控制吞吐量的大小。MaxGCPauseMillis参数的值允许是一个大于0的整数,表示毫秒数,收集器会尽可能的保证每次垃圾收集耗费的时间不超过这个设定值。但是如果这个这个值设定的过小,那么Parallel Scavenge收集器为了保证每次垃圾收集的时间不超过这个限定值,会导致垃圾收集的次数增加和增加年轻代的空间大小,垃圾收集的吞吐量也会随之下降。GCTimeRatio这个参数的值应该是一个0-100之间的整数,表示应用程序运行时间和垃圾收集时间的比值。如果把值设置为19,即系统运行时间 : GC收集时间 = 19 : 1,那么GC收集时间就占用了总时间的5%(1 / (19 + 1) = 5%),该参数的默认值为99,即最大允许1%(1 / (1 + 99) = 1%)的垃圾收集时间。

      Parallel Scavenge收集器还有一个参数:-XX:UseAdaptiveSizePolicy。这是一个开关参数,当开启这个参数以后,就不需要手动指定新生代的内存大小(-Xmn)、Eden区和Survivor区的比值(-XX:SurvivorRatio)以及晋升到老年代的对象的大小(-XX:PretenureSizeThreshold)等参数了,虚拟机会根据当前系统的运行情况动态调整合适的设置值来达到合适的停顿时间和合适的吞吐量,这种方式称为GC自适应调节策略。

      Parallel Scavenge收集器也是一款多线程收集器,但是由于目的是为了控制系统的吞吐量,所以这款收集器也被称为吞吐量优先收集器。


    2.老年代收集器

      老年代收集包括:Serial Old收集器、Parallel Old收集器以及CMS收集器。

    2.1 Serial Old收集器

      Serial Old收集器是Serial收集器的老年代版本,它也是一款使用"标记-整理(标记-压缩)"算法的单线程的垃圾收集器,主要使用在Client模式下的虚拟机。这款收集器主要用于客户端应用程序中作为老年代的垃圾收集器,也可以作为服务端应用程序的垃圾收集器,当它用于服务端应用系统中的时候,主要是在 JDK 5 版本之前和Parallel Scavenge年轻代收集器配合使用,或者作为CMS收集器的后备收集器。

    Serial Old收集器

    2.2 Parallel Old收集器

      Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用"标记-整理"算法。这个收集器是在 JDK 6 版本中出现的,所以在 JDK 6 之前,新生代的Parallel Scavenge只能和Serial Old这款单线程的老年代收集器配合使用。Parallel Old垃圾收集器和Parallel Scavenge收集器一样,也是一款关注吞吐量的垃圾收集器,和Parallel Scavenge收集器一起配合,可以实现对Java堆内存的吞吐量优先的垃圾收集策略。

      Parallel Old垃圾收集器的工作原理和Parallel Scavenge收集器类似。

    Parallel Old收集器

    2.3 CMS收集器

      CMS收集器是老年代收集器中比较优秀的垃圾收集器。CMS是Concurrent Mark Sweep,从名字可以看出,这是一款使用"标记-清除"算法的并发收集器。CMS
    垃圾收集器的目标是解决Serial GC停顿的问题,以获取最短停顿(回收)时间。由于现代互联网中的应用,比较重视服务的响应速度和系统的停顿时间,因其高并发、高响应的特点故常应用于B/S架构。(对 JDK 9 及以上版本的HotSpot虚拟机使用参数-XX:+UseConcMarkSweepGC来开启CMS收集器的话,用户会收到一个警告信息,提示CMS未来将会被废弃;在 JDK 14 中使用-XX:+UseConcMarkSweepGC的话,JVM不会报错,只是给出一个warning信息,但是不会exit。JVM会自动回退以默认GC方式启动JVM。前辈珍重,走好不送。)

      CMS收集器的优点:并发收集、低停顿,但远没有达到完美;

      CMS收集器的缺点

        CMS收集器对CPU资源非常敏感,在并发阶段虽然不会导致用户停顿,但是会占用CPU资源而导致应用程序变慢,总吞吐量下降。
        CMS收集器无法处理浮动垃圾,可能出现“Concurrnet Mode Failure”,失败而导致另一次的Full GC。
        CMS收集器是基于标记-清除算法的实现,因此也会产生碎片。

      CMS收集器的运行过程相对上面提到的几款收集器要复杂一些,如下图示:

    CMS收集器

      从图中可以看出,CMS收集器的工作过程可以分为4个阶段:

         初始标记(CMS initial mark)阶段
         并发标记(CMS concurrent mark)阶段
         重新标记(CMS remark)阶段
         并发清除(CMS concurrent sweep)阶段

      从图中可以看出,在这4个阶段中,初始标记和重新标记这两个阶段都是只有GC线程在运行,用户线程会被停止,所以这两个阶段会发送STW(Stop The World)。初始标记阶段的工作是标记GC Roots可以直接关联到的对象,速度很快。并发标记阶段,会从GC Roots 出发,标记处所有可达的对象,这个过程可能会花费相对比较长的时间,但是由于在这个阶段,GC线程和用户线程是可以一起运行的,所以即使标记过程比较耗时,也不会影响到系统的运行。重新标记阶段,是对并发标记期间因用户程序运行而导致标记变动的那部分记录进行修正,重新标记阶段耗时一般比初始标记稍长,但是远小于并发标记阶段。最终,会进行并发清理阶段,和并发标记阶段类似,并发清理阶段不会停止系统的运行,所以即使相对耗时,也不会对系统运行产生大的影响。

      由于并发标记和并发清理阶段是和应用系统一起执行的,而初始标记和重新标记相对来说耗时很短,所以可以认为CMS收集器在运行过程中,是和应用程序是并发执行的。由于CMS收集器是一款并发收集和低停顿的垃圾收集器,所以CMS收集器也被称为并发低停顿收集器。

      虽然CMS收集器可以是实现低延迟并发收集,但是也存在一些不足。

      首先,CMS收集器对CPU资源非常敏感。对于并发实现的收集器而言,虽然可以利用多核优势提高垃圾收集的效率,但是由于收集器在运行过程中会占用一部分的线程,这些线程会占用CPU资源,所以会影响到应用系统的运行,会导致系统总的吞吐量降低。CMS默认开始的回收线程数是(Ncpu + 3) / 4,其中Ncpu是机器的CPU数。所以,当机器的CPU数量为4个以上的时候,垃圾回收线程将占用不少于%25的CPU资源,并且随着CPU数量的增加,垃圾回收线程占用的CPU资源会减少。但是,当CPU资源少于4个的时候,垃圾回收线程占用的CPU资源的比例会增大,会影响到系统的运行,假设有2个CPU的情况下,垃圾回收线程将会占据超过50%的CPU资源。所以,在选用CMS收集器的时候,需要考虑,当前的应用系统,是否对CPU资源敏感。

      其次,CMS收集器在处理垃圾收集的过程中,可能会产生浮动垃圾,由于它无法处理浮动垃圾,所以可能会出现Concurrent Mode Failure问题而导致触发一次Full GC。所谓的浮动垃圾,是由于CMS收集器的并发清理阶段,清理线程是和用户线程一起运行,如果在清理过程中,用户线程产生了垃圾对象,由于过了标记阶段,所以这些垃圾对象就成为了浮动垃圾,CMS无法在当前垃圾收集过程中集中处理这些垃圾对象。由于这个原因,CMS收集器不能像其他收集器那样等到完全填满了老年代以后才进行垃圾收集,需要预留一部分空间来保证当出现浮动垃圾的时候可以有空间存放这些垃圾对象。在 JDK 5 中,默认当老年代使用了68%的时候会激活垃圾收集,这是一个保守的设置,如果在应用中老年代增长不是很快,可以通过参数"-XX:CMSInitiatingOccupancyFraction"控制触发的百分比,以便降低内存回收次数来提供性能。在 JDK 6 中,CMS收集器的激活阀值变成了92%。如果在CMS运行期间没有足够的内存来存放浮动垃圾,那么就会导致"Concurrent Mode Failure"失败,这个时候,虚拟机将启动后备预案,临时启动Serial Old收集器来对老年代重新进行垃圾收集,这样会导致垃圾收集的时间边长,特别是当老年代内存很大的时候。所以对参数"-XX:CMSInitiatingOccupancyFraction"的设置,过高,会导致发生Concurrent Mode Failure,过低,则浪费内存空间。

      CMS的最后一个问题,就是它在进行垃圾收集时使用的"标记-清除"算法。上一篇文章介绍垃圾回收原理的时候,我们讲到"标记-清除"算法,在进行垃圾清理以后,会出现很多内存碎片,过多的内存碎片会影响大对象的分配,会导致即使老年代内存还有很多空闲,但是由于过多的内存碎片,不得不提前触发垃圾回收。为了解决这个问题,CMS收集器提供了一个"-XX:+UseCMSCompactAtFullCollection"参数,用于CMS收集器在必要的时候对内存碎片进行压缩整理。由于内存碎片整理过程不是并发的,所以会导致停顿时间变长。"-XX:+UseCMSCompactAtFullCollection"参数默认是开启的。虚拟机还提供了一个"-XX:CMSFullGCsBeforeCompaction"参数,来控制进行过多少次不压缩的Full GC以后,进行一次带压缩的Full GC,默认值是0,表示每次在进行Full GC前都进行碎片整理。

      虽然CMS收集器存在上面提到的这些问题,但是毫无疑问,CMS当前仍然是非常优秀的垃圾收集器。


      上面简单介绍了多款不同的垃圾收集器,虽然它们的特性不同,但是有些GC收集器可以组合使用来应对不同的应用的业务场景。下图给出了不同收集器以及它们之间是否兼容,互相兼容的收集器可以组合使用。
    垃圾收集器概览


    3.G1收集器

      G1 收集器是 JDK 7 才正式引用的商用收集器,现在已经成为 JDK 9 默认的收集器。前面几款收集器收集的范围都是新生代或者老年代,G1 进行垃圾收集的范围是整个堆内存,它采用 “ 化整为零 ” 的思路,把整个堆内存划分为多个大小相等的独立区域(Region),每个Region是逻辑连续的一段内存,在 G1 收集器中还保留着新生代和老年代的概念,它们分别都是一部分 Region,如下图:

    G1收集器

      每个Region被标记了E、S、O和H,说明每个Region在运行时都充当了一种角色,其中H是以往算法中没有的,它代表Humongous,这表示这些Region存储的是巨型对象(humongous object,H-obj),如果一个对象占用的空间达到或者超过了分区容量50%以上,G1收集器就认为这是一个巨型对象。这些巨型对象,默认直接会被分配在老年代,但是如果它是一个短期存在的巨型对象,就会对垃圾收集器造成负面影响。为了解决这个问题,G1划分了一个Humongous区,它用来专门存放巨型对象。如果一个H区装不下一个巨型对象,那么G1会寻找连续的H分区来存储。为了能找到连续的H区,有时候不得不启动Full GC。

      每个区域可能是 Eden、Survivor、老年代,每种区域的数量也不一定。JVM 启动时会自动设置每个区域的大小(1M ~ 32M,必须是 2 的次幂),最多可以设置 2048 个区域(即支持的最大堆内存为 32M*2048 = 64G),假如设置 -Xmx8g -Xms8g,则每个区域大小为 8g/2048=4M。

      为了在 GC Roots Tracing 的时候避免扫描全堆,在每个 Region 中,都有一个 Remembered Set 来实时记录该区域内的引用类型数据与其他区域数据的引用关系(在前面的几款分代收集中,新生代、老年代中也有一个 Remembered Set 来实时记录与其他区域的引用关系),在标记时直接参考这些引用关系就可以知道这些对象是否应该被清除,而不用扫描全堆的数据。RSet记录了其他Region中的对象引用本Region中对象的关系,属于points-into结构(谁引用了我的对象)。RSet的价值在于使得垃圾收集器不需要扫描整个堆找到谁引用了当前分区中的对象,只需要扫描RSet即可。

      这里引入了卡表的技术,考虑如下场景,在Young GC的时候,老年代的对象可能引用新生代的对象,那么在标记年轻代存活对象的时候,就需要全堆扫描老年代中的所有对象才能确定那些该回收那些不该回收,成本极高。HotSpot给出的解决方案是一项叫做卡表(Card Table)的技术。该技术将整个堆划分为一个个大小介于128到512字节的卡,并且维护一个卡表,用来存储每张卡的一个标识位。这个标识位代表对应的卡是否可能存有指向新生代对象的引用。如果可能存在,那么我们就认为这张卡是脏的。在进行Minor GC的时候,我们便可以不用扫描整个老年代,而是在卡表中寻找脏卡,并将脏卡中的对象加入到Minor GC的GC Roots里。当完成所有脏卡的扫描之后,Java虚拟机便会将所有脏卡的标识位清零。想要保证每个可能有指向新生代对象引用的卡都被标记为脏卡,那么Java虚拟机需要截获每个引用型实例变量的写操作,并作出对应的写标识位操作。卡表能用于减少老年代的全堆空间扫描,这能很大的提升GC效率。

    卡表

      卡表就是将一个Region区分为若干个card,组成的一张card表,可以将其理解为数组card[i],Rset的存储结构就相当于hashMap,key值为引用当前Region区的另外一个Region区的内存地址,value就是另外一个Region区中引用本Region区的card的索引值,意思就是GC可以通过Rset快速找到是哪个Region的哪个card对本Region进行了引用。

      G1 收集器可以 “ 建立可预测的停顿时间模型 ”,并基于目标来选择进行垃圾回收的区块数量。它维护了一个列表用于记录每个 Region 回收的价值大小(回收后获得的空间大小以及回收所需时间的经验值),这样可以保证 G1 收集器在有限的时间内可以获得最大的回收效率。G1 采用增量回收的方式,每次回收一些区块,而不是整堆回收。它会尽力满足我们的停顿时间要求,但也不是绝对的,它基于之前垃圾收集的数据统计,估计出在用户指定的停顿时间内能收集多少个区块。
      MixedGC的过程:如下图所示,G1 收集器收集器收集过程有初始标记、并发标记、最终标记、筛选回收,和 CMS 收集器前几步的收集过程很相似:如下图所示,G1 收集器收集器收集过程有初始标记、并发标记、最终标记、筛选回收,和 CMS 收集器前几步的收集过程很相似:

    G1收集过程

      ① 初始标记:标记出 GC Roots 直接关联的对象,这个阶段速度较快,需要停止用户线程,单线程执行。

      ② 并发标记:从 GC Root 开始对堆中的对象进行可达新分析,找出存活对象,这个阶段耗时较长,但可以和用户线程并发执行。

      ③ 最终标记:修正在并发标记阶段引用户程序执行而产生变动的标记记录。

      ④ 筛选回收:筛选回收阶段会对各个 Region 的回收价值和成本进行排序,根据用户所期望的 GC 停顿时间来指定回收计划(用最少的时间来回收包含垃圾最多的区域,这就是 Garbage First 的由来——第一时间清理垃圾最多的区块),这里为了提高回收效率,并没有采用和用户线程并发执行的方式,而是停顿用户线程。这些垃圾回收被称作“混合式”是因为他们不仅仅进行正常的新生代垃圾收集,同时也回收部分后台扫描线程标记的分区。

      垃圾回收的并发标记阶段,gc线程和应用线程是并发执行的,所以一个对象被标记之后,应用线程可能篡改对象的引用关系,从而造成对象的漏标、误标,其实误标没什么关系,顶多造成浮动垃圾,在下次gc还是可以回收的,但是漏标的后果是致命的,把本应该存活的对象给回收了,从而影响的程序的正确性。为了解决在并发标记过程中,存活对象漏标的情况,GC HandBook把对象分成三种颜色,也就是常提及到的三色标记法

      适用场景:要求尽可能可控 GC 停顿时间;内存占用较大的应用。可以用 -XX:+UseG1GC 使用 G1 收集器,JDK 9 默认使用 G1 收集器。


    4.三色标记法与现代垃圾回收器

      现代追踪式(可达性分析)的垃圾回收器几乎都借鉴了三色标记的算法思想,尽管实现的方式不尽相同:比如白色/黑色集合一般都不会出现(但是有其他体现颜色的地方)、灰色集合可以通过栈/队列/缓存日志等方式进行实现、遍历方式可以是广度/深度遍历等等。

      对于读写屏障,以Java HotSpot VM为例,其并发标记时对漏标的处理方案如下:
        CMS:写屏障 + 增量更新
        G1:写屏障 + SATB
        ZGC:读屏障

      工程实现中,读写屏障还有其他功能,比如写屏障可以用于记录跨代/区引用的变化,读屏障可以用于支持移动对象的并发执行等。功能之外,还有性能的考虑,所以对于选择哪种,每款垃圾回收器都有自己的想法。

      值得注意的是,CMS中使用的增量更新,在重新标记阶段,除了需要遍历 写屏障的记录,还需要重新扫描遍历GC Roots(当然标记过的无需再遍历了),这是由于CMS对于astore_x等指令不添加写屏障的原因,具体可参考这里


    5.几种垃圾收集器对比及使用场景

    收集器年轻代老年代算法适用场景
    Serial复制Client 模式(桌面应用);单核服务器。可以用 -XX:+UserSerialGC 来选择 Serial 作为新生代收集器。
    ParNew复制多核服务器;与 CMS 收集器搭配使用。当使用 -XX:+UserConcMarkSweepGC 来选择 CMS 作为老年代收集器时,新生代收集器默认就是 ParNew,也可以用 -XX:+UseParNewGC 来指定使用 ParNew 作为新生代收集器。
    Parallel Scavenge复制注重吞吐量,高效利用 CPU,需要高效运算且不需要太多交互。可以使用 -XX:+UseParallelGC 来选择 Parallel Scavenge 作为新生代收集器,jdk7、jdk8 默认使用 Parallel Scavenge 作为新生代收集器。
    Serial Old标记-整理Client 模式(桌面应用);单核服务器;与 Parallel Scavenge 收集器搭配;作为 CMS 收集器的后备预案。
    Parallel Old标记-整理与Parallel Scavenge 收集器搭配使用;注重吞吐量。jdk7、jdk8 默认使用该收集器作为老年代收集器,使用 -XX:+UseParallelOldGC 来指定使用 Paralle Old 收集器。
    CMS标记-清除重视服务器响应速度,要求系统停顿时间最短。可以使用 -XX:+UserConMarkSweepGC 来选择 CMS 作为老年代收集器。
    G1年轻代:复制
    老年代:标记-整理
    要求尽可能可控 GC 停顿时间;内存占用较大的应用。可以用 -XX:+UseG1GC 使用 G1 收集器,jdk9 默认使用 G1 收集器。

    参考文章:
      官方文档
      G1详解

    展开全文
  • JVM垃圾收集器详解

    千次阅读 2021-02-12 10:10:10
    说起垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物。事实上,GC的历史远比Java久远,1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言。当List还在胚胎...

    说起垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物。事实上,GC的历史远比Java久远,1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言。当List还在胚胎时期时,人们就在思考GC需要完成的3件事情:

    哪些内存需要回收?

    什么时候回收?

    如何回收?

    一、哪些内存需要回收?

    从JVM区域结构看,可将这些区域划分为“静态内存”和“动态内存”两类。程序计数器、虚拟机栈、本地方法3个区域是“静态”的,因为这几个区域的内存分配和回收都具备确定性,都随着线程而生,随着线程而灭。但Java堆和方法区不一样,内存分配都存在不确定性,只有在程序处于运行期间才能知道会创建哪些对象,这部分内存和回收都是动态的,垃圾收集器所关注的是这部分内存。

    在堆里面存放着Java世界几乎所有的对象实例,垃圾回收器在对堆进行回收前,第一件事情就是就是要确定这些对象哪些还"存活"着,哪些已经"死去"。那么又怎么确定对象已经"死去"呢?

    1.引用计数法:

    分配对象时给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是没有再被使用了。客观地说,引用计数法(Reference Counting)的实现简单,判断效率也很高,但是在主流的Java虚拟机里面没有选用引用计数法来管理内存,其中最主要的原因是它很难解决对象之间相互循环引用的问题。例如:

    public class ReferenceCountingGC {

    public Object instance = null;

    private byte[] bigsize = new byte[2*1024*1024];

    public static void testGC(){

    ReferenceCountingGC objA = new ReferenceCountingGC();

    ReferenceCountingGC objB = new ReferenceCountingGC();

    objA.instance = objB;

    objB.instance = objA;

    objA = null;

    objB = null;

    System.gc();

    }

    }

    当设置objA = null;objB = null后这两个对象再无任何引用,实际上这两个对象已经不可能再被访问,但是它们因为互相引用着对方,导致它们的引用计数都不为0,于是引用计数算法无法通知GC收集器回收它们。如果这个对象特别大,则会造成严重的内存泄露。

    2.可达性分析算法:

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

    2c954d69c31bb3d1ebc24c1ad836a9ea.png

    对象Object5、Object6、Object7相互虽然有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。在Java语言中,可作为GC Roots的对象包括下面几种:

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

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

    方法区中常量引用的对象。

    本地方法栈中JNI(即一般说的Native方法)引用的对象。

    二、什么时候回收?

    虚拟机为了分析GC Roots这项工作必须在一个能确保一致性的快照中进行,这里的“一致性”的意思就是指在整个分析期间整个执行系统看起来就像被冻结在某个时间点上——这叫安全点。当然,程序执行时并非在所有地方都能停顿下来开始GC,只有到达安全点时才能暂停。安全点选址也有规定的,选定基本上是以程序“是否具有让程序长时间执行的特征”为标准进行选定的。这里的长时间执行的最明显特征是指令列复用,例如方法调用、循环跳转、异常跳转等。

    虚拟机为了能让所有线程都“跑”到安全点上停顿下来,设计了两个方案:抢先式中断和主动式中断。其中抢先式中断是虚拟机发生GC时,首先把所有线程全部中断,如果发生有线程中断的地方不在安全点上,就恢复线程,让它“跑”到安全点上。这种方式现在比较用了。而主动式中断是虚拟机需要GC时仅仅简单的设置一个标志,各个线程执行到安全点时主动去轮询这个标志,发现中断标志为真时就自己中断挂起。

    三、如何回收?

    3.1 垃圾收集算法:

    (1)标记-清除(Mark-Sweep)算法

    这是最基础的算法,就像它名字一样,算法分为“标记”和“清除”两个阶段:首先标记处所有需要回收的对象(如哪些内存需要回收所描述的对象),对标记完成后统一回收所有被标记的对象,如下图所示:

    0dde5a407db43eed5cd7a4846d8d457a.png

    缺点:一个是效率问题,标记和清除两个过程的效率都不高;另一个是空间问题,标记清除后悔产生大量的不连续的内存碎片,可能会导致后续无法分配大对象而导致再一次触发垃圾收集动作。

    (2)复制算法

    为了针对标记-清除算法的不足,复制算法将可用内存容量划分为大小相等的两块,每次只使用一块。当一块的内存用完了,就将还存活的对象复制到另一块上面去。然后把已使用过的内存空间一次清理掉,如下图所示:

    896b92a892acbdbf26b0189c5c363a3a.png

    缺点:使用内存比原来缩小了一半。

    现在的商业虚拟机都采用这种收集算法来回收新生代,有企业分析的得出其实并不需求将内存按1:1的比例划分,因为新生代中的对象大部分都是“朝生夕死”的。所以,HotSpot虚拟机默认的Eden和Survivor的大小比例是8:1。一块Eden和两块Survivor,每次使用一块Eden和一块Survivor,也就是说只有10%是浪费的。如果另一块Survivor都无法存放上次垃圾回收的对象时,那这些对象将通过“担保机制”进入老年代了。

    (3)标记-整理(Mark-Compact)算法

    复制算法一般是对对象存活率较低的一种回收操作,但对于对象存活率较高的内存区域(老年代)来说,效果就不是那么理想了,标记-整理算法因此诞生了。标记-整理算法和标记-清除算法差不多,都是一开始对回收对象进行标记,但后续不是直接对对象清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存,如下图所示:

    2b346b86bb536e3c1f21bd9a5dddb786.png

    (4)分代收集算法

    分代收集算法是目前大部分JVM的垃圾收集器采用的算法。它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),老年代的特点是每次垃圾收集时只有少量对象需要被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,那么就可以根据不同代的特点采取最适合的收集算法。

    3.2 垃圾收集器:

    (1)七种垃圾收集器:

    Serial(串行GC)-复制

    ParNew(并行GC)-复制

    Parallel Scavenge(并行回收GC)-复制

    Serial Old(MSC)(串行GC)-标记-整理

    CMS(并发GC)-标记-清除

    Parallel Old(并行GC)--标记-整理

    G1(JDK1.7update14才可以正式商用)

    说明:

    1~3用于年轻代垃圾回收:年轻代的垃圾回收称为minor GC

    4~6用于年老代垃圾回收(当然也可以用于方法区的回收):年老代的垃圾回收称为full GC

    G1独立完成"分代垃圾回收"

    注意:并行与并发

    并行:多条垃圾回收线程同时操作

    并发:垃圾回收线程与用户线程一起操作

    (2)常用五种组合:

    Serial/Serial Old

    ParNew/Serial Old:与上边相比,只是比年轻代多了多线程垃圾回收而已

    ParNew/CMS:当下比较高效的组合

    Parallel Scavenge/Parallel Old:自动管理的组合

    G1:最先进的收集器,但是需要JDK1.7update14以上

    (2.1)Serial/Serial Old:

    dfa1842b1464fafaaed6786c671baa0a.png

    特点:

    年轻代Serial收集器采用单个GC线程实现"复制"算法(包括扫描、复制)

    年老代Serial Old收集器采用单个GC线程实现"标记-整理"算法

    Serial与Serial Old都会暂停所有用户线程(即STW)

    说明:

    STW(stop the world):编译代码时为每一个方法注入safepoint(方法中循环结束的点、方法执行结束的点),在暂停应用时,需要等待所有的用户线程进入safepoint,之后暂停所有线程,然后进行垃圾回收。

    适用场合:

    CPU核数<2,物理内存<2G的机器(简单来讲,单CPU,新生代空间较小且对STW时间要求不高的情况下使用)

    -XX:UseSerialGC:强制使用该GC组合

    -XX:PrintGCApplicationStoppedTime:查看STW时间

    由于它实现相对简单,没有线程相关的额外开销(主要指线程切换与同步),因此非常适合运行于客户端PC的小型应用程序,或者桌面应用程序(比如swing编写的用户界面程序),以及我们平时的开发、调试、测试等。

    (2.2)ParNew/Serial Old:

    2f5b403d4c9773fe803dac47b8e5715a.png

    说明:

    ParNew除了采用多GC线程来实现复制算法以外,其他都与Serial一样,但是此组合中的Serial Old又是一个单GC线程,所以该组合是一个比较尴尬的组合,在单CPU情况下没有Serial/Serial Old速度快(因为ParNew多线程需要切换),在多CPU情况下又没有之后的三种组合快(因为Serial Old是单GC线程),所以使用其实不多。

    -XX:ParallelGCThreads:指定ParNew GC线程的数量,默认与CPU核数相同,该参数在于CMS GC组合时,也可能会用到

    (2.3)Parallel Scavenge/Parallel Old:

    14d1e44a99354415878613e2962244dc.png

    特点:

    年轻代Parallel Scavenge收集器采用多个GC线程实现"复制"算法(包括扫描、复制)

    年老代Parallel Old收集器采用多个GC线程实现"标记-整理"算法

    Parallel Scavenge与Parallel Old都会暂停所有用户线程(即STW)

    说明:

    吞吐量:CPU运行代码时间/(CPU运行代码时间+GC时间)

    CMS主要注重STW的缩短(该时间越短,用户体验越好,所以主要用于处理很多的交互任务的情况)

    Parallel Scavenge/Parallel Old主要注重吞吐量(吞吐量越大,说明CPU利用率越高,所以主要用于处理很多的CPU计算任务而用户交互任务较少的情况)

    参数设置:

    -XX:+UseParallelOldGC:使用该GC组合

    -XX:GCTimeRatio:直接设置吞吐量大小,假设设为19,则允许的最大GC时间占总时间的1/(1 +19),默认值为99,即1/(1+99)

    -XX:MaxGCPauseMillis:最大GC停顿时间,该参数并非越小越好

    -XX:+UseAdaptiveSizePolicy:开启该参数,-Xmn/-XX:SurvivorRatio/-XX:PretenureSizeThreshold这些参数就不起作用了,虚拟机会自动收集监控信息,动态调整这些参数以提供最合适的的停顿时间或者最大的吞吐量(GC自适应调节策略),而我们需要设置的就是-Xmx,-XX:+UseParallelOldGC或-XX:GCTimeRatio两个参数就好(当然-Xms也指定上与-Xmx相同就好)

    适用场合:

    很多的CPU计算任务而用户交互任务较少的情况

    不想自己去过多的关注GC参数,想让虚拟机自己进行调优工作

    对吞吐量要求较高,或需要达到一定的量。

    (2.4)ParNew/CMS:

    b3923f5ba7fff12849a3e0338804c4b1.png

    说明:

    以上只是年老代CMS收集的过程,年轻代ParNew看"2.2、ParNew/Serial Old"就好

    CMS是多回收线程的,不要被上图误导,默认的线程数:(CPU数量+3)/4

    CMS主要注重STW的缩短(该时间越短,用户体验越好,所以主要用于处理很多的交互任务的情况)

    特点:

    1.年轻代ParNew收集器采用多个GC线程实现"复制"算法(包括扫描、复制)

    2.年老代CMS收集器采用多线程实现"标记-清除"算法

    初始标记:标记与根集合节点直接关联的节点。时间非常短,需要STW

    并发标记:遍历之前标记到的关联节点,继续向下标记所有存活节点。时间较长。

    重新标记:重新遍历trace并发期间修改过的引用关系对象。时间介于初始标记与并发标记之间,通常不会很长。需要STW

    并发清理:直接清除非存活对象,清理之后,将该线程占用的CPU切换给用户线程

    3.初始标记与重新标记都会暂停所有用户线程(即STW),但是时间较短;并发标记与并发清理时间较长,但是不需要STW

    关于并发标记期间怎样记录发生变动的引用关系对象,在重新标记期间怎样扫描这些对象

    缺点:

    并发标记与并发清理:按照说明的第二点来讲,假设有2个CPU,那么其中有一个CPU会用于垃圾回收,而另一个用于用户线程,这样的话,之前是两CPU运行用户线程,现在是一个,那么效率就会急剧下降。也就是说,降低了吞吐量(即降低了CPU使用率)。

    并发清理:在这一过程中,产生的垃圾无法被清理(因为发生在重新标记之后)

    并发标记与并发清理:由于是与用户线程并发的,所以用户线程可能会分配对象,这样既可能对象直接进入年老代(例如,大对象),也可能进入年轻代后,年轻代发生minor GC,这样的话,实际上要求我们的年老代需要预留一定空间,也就是说要在年老代还有一定空间的情况下就要进行垃圾回收,留出一定内存空间来供其他线程使用,而不能等到年老代快爆满了才进行垃圾回收,通过-XX:CMSInitiatingOccupancyFraction来指定当年老代空间满了多少后进行垃圾回收

    标记-清理算法:会产生内存碎片,由于是在老年代,可能会提前触发Full GC(这正是我们要尽量减少的)

    参数设置:

    -XX:+UseConcMarkSweepGC:使用该GC组合

    -XX:CMSInitiatingOccupancyFraction:指定当年老代空间满了多少后进行垃圾回收

    -XX:+UseCMSCompactAtFullCollection:(默认是开启的)在CMS收集器顶不住要进行FullGC时开启内存碎片整理过程,该过程需要STW

    -XX:CMSFullGCsBeforeCompaction:指定多少次FullGC后才进行整理

    -XX:ParallelCMSThreads:指定CMS回收线程的数量,默认为:(CPU数量+3)/4

    适用场合:

    用于处理很多的交互任务的情况

    方法区的回收一般使用CMS,配置两个参数:-XX:+CMSPermGenSweepingEnabled与-XX:+CMSClassUnloadingEnabled

    适用于一些需要长期运行且对相应时间有一定要求的后台程序

    (2.5)G1

    635fe31772a1ba7ba36e747f0f007c56.png

    说明:

    从上图来看,G1与CMS相比,仅在最后的"筛选回收"部分不同(CMS是并发清除),实际上G1回收器的整个堆内存的划分都与其他收集器不同。

    CMS需要配合ParNew,G1可单独回收整个空间

    原理:

    G1收集器将整个堆划分为多个大小相等的Region

    G1跟踪各个region里面的垃圾堆积的价值(回收后所获得的空间大小以及回收所需时间长短的经验值),在后台维护一张优先列表,每次根据允许的收集时间,优先回收价值最大的region,这种思路:在指定的时间内,扫描部分最有价值的region(而不是扫描整个堆内存),并回收,做到尽可能的在有限的时间内获取尽可能高的收集效率。

    运作流程:

    初始标记:标记出所有与根节点直接关联引用对象。需要STW

    并发标记:遍历之前标记到的关联节点,继续向下标记所有存活节点。在此期间所有变化引用关系的对象,都会被记录在Remember Set Logs中

    最终标记:标记在并发标记期间,新产生的垃圾。需要STW

    筛选回收:根据用户指定的期望回收时间回收价值较大的对象(看"原理"第二条)。需要STW

    优点:

    停顿时间可以预测:我们指定时间,在指定时间内只回收部分价值最大的空间,而CMS需要扫描整个年老代,无法预测停顿时间

    无内存碎片:垃圾回收后会整合空间,CMS采用"标记-清理"算法,存在内存碎片

    筛选回收阶段:

    由于只回收部分region,所以STW时间我们可控,所以不需要与用户线程并发争抢CPU资源,而CMS并发清理需要占据一部分的CPU,会降低吞吐量。

    由于STW,所以不会产生"浮动垃圾"(即CMS在并发清理阶段产生的无法回收的垃圾)

    适用范围:

    追求STW短:若ParNew/CMS用的挺好,就用这个;若不符合,用G1

    追求吞吐量:用Parallel Scavenge/Parallel Old,而G1在吞吐量方面没有优势

    以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持脚本之家!

    展开全文
  • web信息收集

    千次阅读 2021-08-03 10:42:43
    文章目录一、域名信息whois查询whois反查备案信息查询二、子域名通过证书收集Google语法工具爆破枚举在线查询三、旁站、C段四、网站信息1、网站架构探测1、指纹检测国外指纹识别工具国内指纹识别工具在线指纹识别2、...


    参考博客:https://www.freebuf.com/articles/web/250416.html

    #小迪信息收集流程图(参考)

    image-20210802202954491

    一、域名信息

    whois查询

    whois信息在线收集地址
    站长之家: http://whois.chinaz.com/
    阿里云域名信息查询:https://whois.aliyun.com
    爱站:https://whois.aizhan.com/
    微步:https://x.threatbook.cn/

    whois反查

    站长之家:http://whois.chinaz.com
    whois反查可根据whois获取到的域名所有人、域名注册商、域名注册日期和过期日期等,使用邮箱,电话等进行反查获取更多关联的域名等信息

    备案信息查询

    常用备案信息查询网站,获取网站的详细信息
    ICP备案查询网:http://www.beianbeian.com/
    天眼查:https://www.tianyancha.com/
    爱站网:https://www.aizhan.com/

    二、子域名

    通过证书收集

    https://censys.io/
    https://crt.sh/

    Google语法

    利用搜索引擎查询(site:www.xxx.com)

    工具爆破枚举

    layer子域名挖掘机、御剑、subDomainsBrute、K8

    oneforall

    image-20210803101926592

    在线查询

    http://sbd.ximcx.cn/
    站长工具:http://tool.chinaz.com/subdomain/

    三、旁站、C段

    旁站:是和目标网站在同一台服务器上的其它网站

    C端:是和服务器IP处在一个C段的其他服务器

    在线:
    https://webscan.cc/

    fofa、shodan在线工具 语法:ip=“106.15.141.18/24”

    本地:

    namp

    nmap -p 22,21,443,8080-Pn 172.178.40.0/24

    masscan

    masscan -p 22,21,443,8080-Pn --rate=1000172.178.40.0/24

    goby 自动探测当前网络空间存活的IP及解析域名到IP

    K8旁站 K8Cscan是款专用于大型内网渗透的高并发插件化扫描神器,可以用来扫描C段、旁站

    御剑1.5这个就不用多说什么了

    四、网站信息

    image-20210802212440693

    1、网站架构探测

    探测目标站点架构:操作系统、中间件、脚本语言、数据库、服务器、web容器。

    1、指纹检测

    组件是网络空间最小的单元,WEB应用程序、数据库、中间件等都属于组件。指纹是组件上能标识对象类型的一段特征信息,用来在渗透测试信息收集环节中快速识别目标服务。指纹识别可以通过一些开源程序和小工具进行扫描,也可以结合文件头和反馈信息进行手工判断,指纹识别的主要思路如下:

    • 使用工具自动判断
    • 手工对网站的关键字、版权信息、后台登录、程序版本和rebots.txt等常见固有文件进行识别、查找、对比,相同文件具有相同的MD5值或相同的属性

    指纹检测详细解释:https://www.anquanke.com/post/id/178230

    国外指纹识别工具

    WhatWeb

    Wapplyzer

    Whatruns跟Wappalyzer安装类似,Whatruns可直接在chrome应用商城直接搜索安装

    国内指纹识别工具

    御剑web指纹识别程序

    Test404轻量WEB指纹识别

    w11scan分布式WEB指纹识别平台

    在线指纹识别

    使用首先需要将被识别网址保存到文件中,然后打开Test404导入网址文件,点击开始识别即可

    通过域名或IP地址进行查询

    • 云悉指纹识别网址 :http://www.yunsee.cn/finger.html
    • bugscaner指纹识别网址:http://whatweb.bugscaner.com/look/

    2、CMS识别

    web渗透过程中,对目标网站的指纹识别比较关键,通过工具或手工来识别CMS系统的自建、二次开发,还是直接使用开源的CMS程序至关重要,通过获取的这些信息来决定后续渗透的测试思路和策略。在指纹识别的过程中,借用了很多开源的工具和指纹库,如fofa、WhatWeb、w11scan、WebEye、御剑等等。

    在线cms指纹识别:http://whatweb.bugscaner.com/look/

    云悉:http://www.yunsee.cn/info.html

    潮汐指纹:http://finger.tidesec.net/

    操作系统类型识别:

    通过ping目标主机返回的TTL值判断服务器类型 win128 linux 64 ,大小写敏感区分

    工具:namp、p0f

    综合探测工具:
    shodan、whatweb(kali集成)、wappalyzer插件

    2、WAF信息

    扫描工具:whatwaf、wafw00f
    在线识别工具:https://scan.top15.cn/web
    扫描IP C段,防火墙一般都会有web管理

    什么是WAF应用?

    Web应用防火墙可以防止Web应用免受各种常见攻击,比如SQL注入,跨站脚本漏洞(XSS)等。WAF也能够监测并过滤掉某些可能让应用遭受DOS(拒绝服务)攻击的流量。WAF会在HTTP流量抵达应用服务器之前检测可疑访问,同时,它们也能防止从Web应用获取某些未经授权的数据。

    WAF的主要特点有:

    1. 针对HTTP和HTTPS的请求进行异常检测,阻断不符合请求的访问,并且严格的限制HTTP协议中没有完全限制的规则。以此来减少被攻击的范围。

    2. 建立安全规则库,严格的控制输入验证,以安全规则来判断应用数据是否异常,如有异常直接阻断。以此来有效的防止网页篡改,信息泄露等恶意攻击的可能性。

    3. 运用WAF技术判断用户是否是第一次请求访问的,同时将请求重定向到默认的登陆页面并且记录该事件。以此来检测识别用户的操作是否存在异常或者攻击,并且对达到阙值,触发规则的访问进行处理。

    4. WAF防御机制也可以用来隐藏表单域保护,响应监控信息泄露或者被攻击时的告警提示,也可以抵抗规避入侵,爬虫等技术。

    如何快速识别WAF?

    工具:wafw00f

    下载地址;https://github.com/EnableSecurity/wafw00f

    直接cmd打开,输入: python setup.py install ,就会自动运行安装程序,最后一行出现下面这句话就是安装成功了

    Finished processing dependencies for wafw00f==2.1.0

    之后,cd 进入wafw00f文件夹,执行 python main.py 就可以开始识别网站waf了

    执行命令 python main.py https://www.bilibili.com/ 进行waf检测

    有识别不出和误报情况

    案例:

    wafw00f案例

    无waf

    手动识别waf

    wafw00f-shodan(X-Powered-By:WAF)字段里面看看是否包含此信息X-Powered-By:WAF,但是此方法不一定有效

    识别WAF对于安全测试的意义?

    对方有waf,不要直接使用扫描工具去扫,因为都会拦截掉,扫了有可能会把ip封了,之后要过一会才能扫了

    3、历史漏洞

    公开漏洞查询

    确认网站的运行的cms或者运行的服务后,可通过公开漏洞进行查询

    http://cve.mitre.org/find/search_tips.html

    通过查询cve漏洞库查找当前cms或者服务是否存在已知公开漏洞,结合google获取详细漏洞信息

    https://www.exploit-db.com/

    Google等搜索引擎确定cms或者服务后,在后面加上exp、poc、漏洞等词汇获取详细漏洞信息。

    https://vulners.com/

    可通过漏洞相关关键字获取详细漏洞信息

    历史漏洞查询

    确认网站所属单位,可通过查询历史漏洞或者该集团、单位历史漏洞辅助攻击(例如获取内网ip段、历史账号密码)

    seebug:https://www.seebug.org/

    CNVD:https://www.cnvd.org.cn/

    五、敏感目录文件

    Web 应用敏感信息探测:

    • 寻找Web 应用的敏感目录、敏感文件、源码泄露。
    • 敏感信息探测工具:
    • wfuzz可以用在做参数的模糊测试,也可以用来做Web目录扫描等操作。
    • 操作指令: wfuzz -w DIR.txt [http://xxx.com/FUZz](http://xxx.com/FUZz)
    • 御剑扫描工具直接一顿扫
    • Fuzzdb

    网页源码

    注意观察源代码里面是否会有开发者预留的相关信息,有时候开发者为图方面会将测试账号密码、默认管理员账号密码写在前端。同时查看源代码里面的一些相对路径的文件和绝对路径的文件,可能会存在未授权访问漏洞。

    工具

    工具:https://github.com/j3ers3/Dirscan

    .git泄露

    工具:https://github.com/denny0223/scrabble

    工具:githacker https://github.com/WangYihang/GitHacker

    在git泄露中也可能有其他有用的信息如在文件下.git/config文件下的access_token信息进而访问该用户的其他仓库。

    SVN泄露

    工具:seay-svn

    dvcs-ripper

    https://github.com/kost/dvcs-ripper

    HG泄露

    工具:https://github.com/kost/dvcs-ripper

    备份文件

    Test404网站备份文件扫描器 v2.0

    Google语法是万能的

    DirBuster(kali自带的一款扫描工具)

    Webdirscan(python编写的简易的扫描工具)

    御剑(操作简易方便)

    dirmap(一款高级web目录扫描工具,功能比较强大)

    这些工具都自带字典,也可以自己手动添加,拥有强大的字典也是很关键的

    五、端口扫描

    需要知道目标服务器开放了哪些端口,常见的如 135 、137 、138 、139 、445,这几个端口经常爆发漏洞。以下是一些服务端口的漏洞:

    22——>ssh弱口令
    873——>rsync 未授权访问漏洞
    3306——>mysql弱口令
    6379——>redis未授权访问漏洞

    端口扫描工具有nmap和masscan。nmap扫描的准确性较高,但是扫描的比较慢。masscan扫描的比较快,但是准确性较低。

    nmap对ip地址进行扫描

    nmap -sV IP

    六、APP以及其他资产

    #AP提取一键反编译提取

    #AP抓数据包进行工具配合

    #各种第三方应用相关探针技术

    #各种服务接口信思相关探针技术

    #APP提取及抓包及后续配合

    某APK一键提取反编译

    利用burp历史抓更多URL

    #某无WEB框架下的第三方测试

    各种端口一顿乱扫-思路

    各种接口一顿乱扫-思路

    接口部分一顿乱扫-思路

    六、网络空间引擎搜索(暗黑引擎)

    简单用法

    三种引擎都能够搜索到很多信息,没有好坏之分

    搜索ip时,可以得到这个ip开放的端口以及具体启动的服务是什么

    比如挖SRC的时候要进行子域名收集,查找真实IP等。如果寻找某电商的子域名,可以根据其证书,header信息,备案号,页面引用的特定文件等找到相关其子域名。对于一些有cdn的,也可以绕过cdn找到真实IP。

    搜索域名的时候,可以得出其子域名以及ip端口等等信息

    1、shodan

    一些有趣的Shodan搜索:https://www.freebuf.com/fevents/224181.html

    2、fofa

    fofa既可以搜索到部分子域名,也可以搜索到目标的各种系统,如OA、后台等等,而这些系统很容易成为突破口

    fofa常用语法+新功能-网络空间测绘 :https://www.freebuf.com/sectool/268246.html

    FOFA搜索语法

    主要分为检索字段以及运算符,所有的查询语句都是由这两种元素组成的。目前支持的检索字段包括:domain,host,ip,title,server,header,body,port,cert,country,city,os,appserver,middleware,language,tags,user_tag等等,支持的逻辑运算符包括:= ,==,!= ,&&,||

    常用命令:

    1.title

    搜索包含“标题”的IP title=“标题”

    2.domain

    搜索所有子域名

    3.host

    搜索host内所有带有qq.com的域名

    新功能:网络空间测绘

    蜜罐:

    蜜罐是一种软件应用系统,用来称当入侵诱饵,引诱黑客前来攻击。攻击者入侵后,通过监测与分析,就可以知道他是如何入侵的,随时了解针对组织服务器发动的最新的攻击和漏洞。还可以通过窃听黑客之间的联系,收集黑客所用的种种工具,并且掌握他们的社交网络。 设置蜜罐并不复杂,只要在外部因特网上有一台计算机运行没有打上补丁的微软Windows或者Red Hat Linux即行,然后在计算机和因特网连接之间安置一套网络监控系统,以便悄悄记录下进出计算机的所有流量。然后只要坐下来,等待攻击者自投罗网。

    3、zoomeye–钟馗之眼

    信息收集利器:ZoomEye:https://www.freebuf.com/sectool/163782.html

    ZoomEye是一款针对网络空间的搜索引擎,收录了互联网空间中的设备、网站及其使用的服务或组件等信息。

    ZoomEye 拥有两大探测引擎:XmapWmap,分别针对网络空间中的设备及网站,通过 24 小时不间断的探测、识别,标识出互联网设备及网站所使用的服务及组件。研究人员可以通过 ZoomEye 方便的了解组件的普及率及漏洞的危害范围等信息。

    虽然被称为 “黑客友好” 的搜索引擎,但ZoomEye 并不会主动对网络设备、网站发起攻击,收录的数据也仅用于安全研究。ZoomEye更像是互联网空间的一张航海图。ZoomEye兼具信息收集的功能与漏洞信息库的资源,对于广大的渗透测试爱好者来说以一件非常不错的利器。

    七、其他社工查询

    1、法人代表

    天眼查 https://www.tianyancha.com/

    whois https://www.whois.com/

    2、灰色产业

    银行卡号归属地 http://cha.yinhangkadata.com/

    友商发票查询 http://fapiao.youshang.com/

    TG社工、四件套查询、开户籍

    查询dns解析以及子域名

    https://securitytrails.com/domain/www.baidu.com/history/a

    https://dnsdb.io/

    ip GPS定位 https://www.opengps.cn/

    证书透明度介绍:

    • 授权机构(CA)是一个受信任的第三方组织,负责发布和管理SSL/TLS证书,全球有数百个受信任的CA,他们中任何一个都有权利为你的域名颁发有效的SSL证书。
    • 证书透明度(CT)是为了防止证书授权机构(CA)或者其他恶意人员伪造服务器证书而诞生的一个项目。
    • CT会要求CA将数字证书(SSL/TLS证书)公开并发布将颁发记录同步到日志服务器中。而日志服务器则会提供给用户一个查找某域名颁发的所有数字证书途径。
    • 原理: “要向用户提供加密流量,网站必须先向可信的证书授权中心 (CA) 申请证书。然后,当用户尝试访问相应网站时,此证书即会被提供给浏览器以验证该网站。近年来,由于 HTTPS 证书系统存在结构性缺陷,证书以及签发证书的 CA 很容易遭到入侵和操纵。Google 的证书透明度项目旨在通过提供一个用于监测和审核 HTTPS 证书的开放式框架,来保障证书签发流程安全无虞。”

    证书透明度工具:

    • Crtsh - 常用 https://crt.sh/
    • Censys - 常用
    • Google
    • Facebook
    • Entrust
    • Certspotter
    • Spyse

    八、github监控

    便于收集整理最新的exp或poc(GitHub上有这个项目,修改一下api就可以接收短信了)

    便于发现相关测试目标的资产

    各种子域名查询

    DNS,备案,证书

    全球节点请求cdn

    枚举爆破或解析子域名对应

    便于发现管理员相关的注册信息

    九、真实IP查询

    1、确定有无CDN

    CDN简介

    CDN 的全称是 Content Delivery Network,即内容分发网络。CDN 是 构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器, 通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所 需内容,降低网络拥塞,提高用户访问响应速度和命中率。但在安全测试过 程中,若目标存在 CDN 服务,将会影响到后续的安全测试过程。

    #如何判断目标存在 CDN 服务?

    利用多节点技术进行请求返回判断

    #CDN 对于安全测试有那些影响?

    #目前常见的 CDN 绕过技术有哪些?

    子域名查询 邮件服务查询 国外地址请求 遗留文件,扫描全网 黑暗引擎搜索特定文件 dns 历史记录,以量打量

    #CDN 真实 IP 地址获取后绑定指向地址 更改本地 HOSTS 解析指向文

    确定有无CDN的方法

    1.多地ping

    看对应IP地址是否唯一,多地ping(超级ping)在线网站:http://ping.chinaz.com/

    2.nslookup

    nslookup 同样是看返回的IP地址的数量进行判断

    2、绕过CDN查找网站真实IP

    1.DNS历史解析

    查看IP与域名绑定的历史记录,可能会存在使用CDN前的记录,相关网站:
    https://dnsdb.io/zh-cn/(全球DNS搜索引擎)
    https://community.riskiq.com/(riskiq)
    https://x.threatbook.cn/(微步在线情报社区)
    https://tools.ipip.net/cdn.php(全球CDN服务商查询)

    2.查询子域名

    毕竟CDN不便宜,所以很多站都是主站做了CDN,而很多小站没做CDN所以可以,通过上面收集到的子域名查询到真实的IP地址

    3.网络空间引擎搜索法

    通过shadan、fofa等搜索引擎,通过对目标网站的特征进行搜索,很多时候可以获取网站的真实IP

    4.利用SSL证书查询

    https://censys.io/certificates/

    5.邮件订阅

    一些网站有发送邮件的功能,如Rss邮件订阅,因为邮件系统一般都在内部,所以就可以通过邮箱获得真实的IP

    6.国外访问

    一般的站点在国内可能会有CDN,但是在国外的用户覆盖率比较低,所以通过国外的节点进行请求往往能获取真实IP

    全球CDN服务商查询https://www.ipip.net/

    ipip网站(全球CDN服务商查询),寻找其真实ip,因为一个ip不可能做到全世界网络分发,使用国外ip去ping这个域名,可以得到其真实ip

    十、服务器信息搜集

    1、操作系统类型判断

    Nmap可以检测目标主机是否在线端口开放情况侦测运行的服务类型及版本信息侦测操作系统与设备类型等信息。它是网络管理员必用的软件之一,用以评估网络系统安全。

    第一种判断方法:

    • 使用Nmap,你可以检测远程主机上运行的操作系统和版本。
    • 操作指令: nmap -O 192.168.0.101
    • 指令模板:nmap -O IP地址
    • 操作指令: nmap -Pn -O 192.168.0.101
    • 指令含义:-Pn 不判断主机存货直接进行系统扫描判断

    第二种判断方法:

    • Windows 系统中不区分大小写,Linux系统中大小写敏感。
    • 举个例子:修改URL中的大小写进行判断,修改之后无影响则是 Windows 反之 则是 Linux 系统

    端口扫描

    端口扫描的时候这些信息都基本上出来了

    nmap -sV ip

    谷歌信息收集插件

    wappalyzer可以得到服务器信息

    抓包工具

    可以通过Burp Suite (BP)进行抓包分析,能发现暴露的信息:搭建框架、服务器信息等

    展开全文
  • Parallel Scavenge收集器 VS CMS等收集器: Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是...

    JDK1.8之前的堆内存示意图:

    183a18fabe3057e0327ace271e2203bb.png

    从上图可以看出堆内存的分为新生代、老年代和永久代。新生代又被进一步分为:Eden 区+Survior1 区+Survior2 区。值得注意的是,在 JDK 1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域(永久代使用的是JVM的堆内存空间,而元空间使用的是物理内存,直接受到本机的物理内存限制)。

    4d3e7770ce6ba8c63520178e6528c115.png

    JVM为什么要进行垃圾回收?

    如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收。除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此。所以,垃圾回收是必须的。

    垃圾收集的定义

    GC是垃圾收集的意思(Gabage Collection),Java提供的GC功能可以自动也只能自动地回收堆内存中不再使用的对象,释放资源(目的),Java语言没有提供释放已分配内存的显式操作方法(gc方法只是通知,不是立即执行)。

    对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。

    垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,当一个对象不再被引用的时候,按照特定的垃圾收集算法来实现资源自动回收的功能。

    那什么时候进行垃圾回收呢?

    1、第一种场景应该很明显,当年轻代或者老年代满了,Java虚拟机无法再为新的对象分配内存空间了,那么Java虚拟机就会触发一次GC去回收掉那些已经不会再被使用到的对象

    2、手动调用System.gc()方法,通常这样会触发一次的Full GC以及至少一次的Minor GC

    3、程序运行的时候有一条低优先级的GC线程,它是一条守护线程,当这条线程处于运行状态的时候,自然就触发了一次GC了。这点也很好证明,不过要用到WeakReference的知识,后面写WeakReference的时候会专门讲到这个。

    我们可以主动垃圾回收吗?

    每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行。java.lang.System.gc()只是java.lang.Runtime.getRuntime().gc()的简写,两者的行为没有任何不同。

    唯一的区别就是System.gc()写起来比Runtime.getRuntime().gc()简单点. 其实基本没什么机会用得到这个命令, 因为这个命令只是建议JVM安排GC运行, 还有可能完全被拒绝。 GC本身是会周期性的自动运行的,由JVM决定运行的时机,而且现在的版本有多种更智能的模式可以选择,还会根据运行的机器自动去做选择,就算真的有性能上的需求,也应该去对GC的运行机制进行微调,而不是通过使用这个命令来实现性能的优化。

    并行和并发的区别

    并行(Parallel)

    88204f593f545fe7e0f9fbd829fbeba7.png

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

    如ParNew、Parallel Scavenge、Parallel Old;

    Tips:通过名字就可以看出来,并行的都带有Parallel关键字,ParNew的Par也是Parallel缩写。

    并发(Concurrent)

    235bf1faca4e96a18b0441269aa2c24e.png

    指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行);

    用户程序在继续运行,而垃圾收集程序线程运行于另一个CPU上;

    如CMS、G1(也有并行);

    Minor GC和Full GC的区别

    Minor GC

    又称新生代GC,指发生在新生代的垃圾收集动作;

    因为Java对象大多是朝生夕灭,所以Minor GC非常频繁,一般回收速度也比较快;

    Full GC

    又称老年代GC,指发生在老年代的GC;

    Full GC速度一般比Minor GC慢10倍以上;

    吞吐量(Throughput)

    吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即

    吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)。

    假设虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。

    四种引用

    Java 中的垃圾回收一般是在 Java 堆中进行,因为堆中几乎存放了 Java 中所有的对象实例。谈到 Java 堆中的垃圾回收,自然要谈到引用。在 JDK1.2 之后,Java 对引用的概念进行了扩充,将其分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)四种,引用强度依次减弱。

    有强到弱分为

    强引用(Strong Reference)

    软引用(Soft Reference)

    弱引用(Weak Reference)

    虚引用(Phantom Reference)

    强引用(Strong Reference)

    如“Object obj = new Object()”,这类引用是 Java 程序中最普遍的。只要强引用还存在,垃圾收集器就永远不会回收掉被引用的对象。

    强引用具备以下三个个特点:

    强引用可以直接访问目标对象;

    强引用所指向的对象在任何时候都不会被系统回收。JVM宁愿抛出OOM异常也不回收强引用所指向的对象;

    强引用可能导致内存泄露;

    软引用(Soft Reference)

    是用来描述一些还有用但并非必须的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。在 JDK 1.2 之后,提供了 SoftReference 类来实现软引用。

    弱引用(Weak Reference)

    用来描述非必须的对象,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发送之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。一旦一个弱引用对象被垃圾回收器回收,便会加入到一个注册引用队列中。在 JDK 1.2 之后,提供了 WeakReference类来实现弱引用。

    Tips:软引用、弱引用都非常适合来保存那些可有可无的缓存数据。如果这么做,当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出。而当内存资源充足时,这些缓存数据又可以存在相当长的时间,从而起到加速系统的作用。

    虚引用(Phantom Reference)

    它是最弱的一种引用关系。一个持有虚引用的对象,和没有引用几乎是一样的,随时都有可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总是会失败。并且,虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收过程。在 JDK 1.2 之后,提供了 PhantomReference类来实现虚引用。

    Stop-The-World

    GC在后台自动发起和自动完成的,在用户不可见的情况下,把用户正常的工作线程全部停掉,即GC停顿,会带给用户不良的体验;

    为什么要Stop-The-World

    可达性分析的时候为了确保快照的一致性,需要对整个系统进行冻结,不可以出现分析过程中对象引用关系还在不断变化的情况,也就是Stop-The-World。

    Stop-The-World是导致GC卡顿的重要原因之一。

    举个例子:

    你在做家务,正在计算家里有多少垃圾的时候,是不能允许别人在这时候清理或者增加垃圾的,否则你的计算将毫无意义。所以在这个时候,你需要把家里的人都关在门外,等你计算好垃圾的数量之后才能让他们进来。

    查看垃圾回收器

    我们知道JVM分Client 和 Server模式。

    如果启动JVM不指定模式,JDK会根据当前的操作系统配置来启动不同模式的JVM。

    默认64bit操作系统下都会是Server模式的JVM。

    # java -XX: +PrintCommandLineFlags –version

    d07dca187c6b269b98a21bd42c544436.png

    垃圾收集器

    JVM是一个进程,垃圾收集器就是一个线程,垃圾收集线程是一个守护线程,优先级低,其在当前系统空闲或堆中老年代占用率较大时触发。

    JDK7/8后,HotSpot虚拟机所有收集器及组合(连线),如下图:

    905d6ab2d7ab33657f218154da525a28.png

    图中展示了7种不同分代的收集器:

    Serial

    ParNew (Serial的升级版,多线程)

    Parallel Scavenge

    Serial Old

    Parallel Old

    CMS

    G1

    新生代收集器还是老年代收集器:

    新生代收集器:Serial、ParNew、Parallel Scavenge;

    老年代收集器:Serial Old、Parallel Old、CMS;

    整堆收集器:G1

    吞吐量优先、停顿时间优先

    吞吐量优先:Parallel Scavenge收集器、Parallel Old 收集器。

    停顿时间优先:CMS(Concurrent Mark-Sweep)收集器。

    吞吐量与停顿时间适用场景

    停顿时间优先:交互多,对响应速度要求高

    吞吐量优先:交互少,计算多,适合在后台运算的场景。

    串行并行并发

    串行:Serial、Serial Old

    并行:ParNew、Parallel Scavenge、Parallel Old

    并发:CMS、G1

    算法

    复制算法:Serial、ParNew、Parallel Scavenge、G1

    标记-清除:CMS

    标记-整理:Serial Old、Parallel Old、G1

    1、Serial收集器

    1c13b8e41120caccd15369497355b588.png

    Serial(串行)垃圾收集器是最基本、发展历史最悠久的收集器;

    JDK1.3.1前是HotSpot新生代收集的唯一选择;

    特点

    针对新生代

    串行

    复制算法

    单线程一方面意味着它只会使用一个CPU或一条线程去完成垃圾收集工作,

    另一方面也意味着在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束为止,这个过程也称为 Stop The world。

    后者意味着,在用户不可见的情况下要把用户正常工作的线程全部停掉,这显然对很多应用是难以接受的。

    应用场景

    对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。

    Serial收集器依然是虚拟机运行在Client模式下的默认新生代收集器。 在用户的桌面应用场景中,可用内存一般不大(几十M至一两百M),可以在较短时间内完成垃圾收集(几十MS至一百多MS),只要不频繁发生,这是可以接受的

    Tips:Stop the World是在用户不可见的情况下执行的,会造成某些应用响应变慢;

    Tips:因为新生代的特点是对象存活率低,所以收集算法用的是复制算法,把新生代存活对象复制到老年代,复制的内容不多,性能较好。

    Tips:单线程地好处就是减少上下文切换,减少系统资源的开销。但这种方式的缺点也很明显,在GC的过程中,会暂停程序的执行。若GC不是频繁发生,这或许是一个不错的选择,否则将会影响程序的执行性能。 对于新生代来说,区域比较小,停顿时间短,所以比较使用。

    参数

    -XX:+UseSerialGC:串联收集器

    Tips:在JDK Client模式,不指定VM参数,默认是串行垃圾回收器

    2、ParNew收集器

    ParNew收集器就是Serial收集器的多线程版本,它也是一个新生代收集器。除了使用多线程进行垃圾收集外,其余行为包括Serial收集器可用的所有控制参数、收集算法(复制算法)、Stop The World、对象分配规则、回收策略等与Serial收集器完全相同,两者共用了相当多的代码。

    ParNew收集器的工作过程如下图:

    111fbad04e83f6fc486c78406621ae05.png

    ParNew收集器除了使用多线程收集外,其他与Serial收集器相比并无太多创新之处,但它却是许多运行在Server模式下的虚拟机中首选的新生代收集器,其中有一个与性能无关的重要原因是,除了Serial收集器外,目前只有它能和CMS收集器(Concurrent Mark Sweep)配合工作,CMS收集器是JDK 1.5推出的一个具有划时代意义的收集器,具体内容将在稍后进行介绍。

    ParNew 收集器在单CPU的环境中绝对不会有比Serial收集器有更好的效果,甚至由于存在线程交互的开销,该收集器在通过超线程技术实现的两个CPU的环境中都不能百分之百地保证可以超越。在多CPU环境下,随着CPU的数量增加,它对于GC时系统资源的有效利用是很有好处的。

    特点

    ParNew收集器其实就是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集外,其余行为和Serial收集器完全一样,包括Serial收集器可用的所有控制参数、收集算法、Stop The world、对象分配规则、回收策略等都一样。在实现上也共用了相当多的代码。

    针对新生代

    复制算法

    串行

    多线程

    GC时需要暂停所有用户线程,直到GC结束

    Serial多线程版本,其他特点与Serial相同

    应用场景

    ParNew收集器是许多运行在Server模式下的虚拟机中首选的新生代收集器。很重要的原因是:除了Serial收集器之外,目前只有它能与CMS收集器配合工作(看图)。在JDK1.5时期,HotSpot推出了一款几乎可以认为具有划时代意义的垃圾收集器-----CMS收集器,这款收集器是HotSpot虚拟机中第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程同时工作。

    参数

    "-XX:+UseConcMarkSweepGC":指定使用CMS后,会默认使用ParNew作为新生代收集器;

    "-XX:+UseParNewGC":强制指定使用ParNew;

    "-XX:ParallelGCThreads":指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相同;

    为什么只有ParNew能与CMS收集器配合

    CMS是HotSpot在JDK1.5推出的第一款真正意义上的并发(Concurrent)收集器,第一次实现了让垃圾收集线程与用户线程(基本上)同时工作;

    CMS作为老年代收集器,但却无法与JDK1.4已经存在的新生代收集器Parallel Scavenge配合工作;

    因为Parallel Scavenge(以及G1)都没有使用传统的GC收集器代码框架,而另外独立实现;而其余几种收集器则共用了部分的框架代码;

    3、Parallel Scavenge收集器

    Parallel Scavenge收集器和ParNew类似,新生代的收集器,同样用的是复制算法,也是并行多线程收集。与ParNew最大的不同,它关注的是垃圾回收的吞吐量。

    特点

    针对新生代

    复制算法

    并行

    多线程

    高吞吐量为目标

    应用场景

    Parallel Scavenge收集器是虚拟机运行在Server模式下的默认垃圾收集器。

    高吞吐量为目标,即减少垃圾收集时间,让用户代码获得更长的运行时间;适合那种交互少、运算多的场景

    例如,那些执行批量处理、订单处理、工资支付、科学计算的应用程序;

    参数

    "-XX:+MaxGCPauseMillis":控制最大垃圾收集停顿时间,大于0的毫秒数;这个参数设置的越小,停顿时间可能会缩短,但也会导致吞吐量下降,导致垃圾收集发生得更频繁。

    "-XX:GCTimeRatio":设置垃圾收集时间占总时间的比率,0

    先垃圾收集执行时间占应用程序执行时间的比例的计算方法是:

    1 / (1 + n)

    例如,选项-XX:GCTimeRatio=19,设置了垃圾收集时间占总时间的5%=1/(1+19);

    默认值是1%--1/(1+99),即n=99;

    垃圾收集所花费的时间是年轻一代和老年代收集的总时间;

    此外,还有一个值得关注的参数:

    "-XX:+UseAdptiveSizePolicy"

    开启这个参数后,就不用手工指定一些细节参数,如:

    新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRation)、晋升老年代的对象年龄(-XX:PretenureSizeThreshold)等;

    JVM会根据当前系统运行情况收集性能监控信息,动态调整这些参数,以提供最合适的停顿时间或最大的吞吐量,这种调节方式称为GC自适应的调节策略(GC Ergonomiscs);

    另外值得注意的一点是,Parallel Scavenge收集器无法与CMS收集器配合使用,所以在JDK 1.6推出Parallel Old之前,如果新生代选择Parallel Scavenge收集器,老年代只有Serial Old收集器能与之配合使用。

    Parallel Scavenge收集器 VS CMS等收集器:

    Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)。

    由于与吞吐量关系密切,Parallel Scavenge收集器也经常称为“吞吐量优先”收集器。

    Parallel Scavenge收集器 VS ParNew收集器:

    Parallel Scavenge收集器与ParNew收集器的一个重要区别是它具有自适应调节策略。

    4、Serial Old收集器(标记-整理算法)

    Serial收集器的工作流程如下图:

    abdedea73525f71775a338dbceeedd2a.png

    如上图所示,Serial 收集器在新生代和老年代都有对应的版本,除了收集算法不同,两个版本并没有其他差异。

    Serial 新生代收集器采用的是复制算法。

    Serial Old 老年代采用的是标记 - 整理算法。

    特性

    Serial Old是Serial的老年代版本,

    除了采用标记-整理算法,其他与Serial相同

    应用场景

    Client模式

    Serial Old收集器的主要意义也是在于给Client模式下的虚拟机使用。

    Server模式

    如果在Server模式下,那么它主要还有两大用途:一种用途是在JDK 1.5以及之前的版本中与Parallel Scavenge收集器搭配使用;另一种用途就是作为CMS收集器的后备预案,在并发收集发生"Concurrent Mode Failure"时使用。

    5、Parallel Old收集器

    e1b908c08120b3323a3d5ca408bc569b.png

    如上图所示,Parallel 收集器在新生代和老年代也都有对应的版本,除了收集算法不同,两个版本并没有其他差异。

    Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量优先

    Parallel Old收集器是Parallel Scavenge收集器的老年版本,它也使用多线程和“标记-整理”算法。这个收集器是在JDK 1.6开始提供。

    Mark-Compact

    特点

    Parallel Old是Parallel Scavenge的老年代版本

    Parallel Old 老年代采用的是标记 - 整理算法,其他特点与Parallel Scavenge相同

    使用场景

    在注重吞吐量以及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器组合。

    JDK1.6及之后用来代替老年代的Serial Old收集器;

    特别是在Server模式,多CPU的情况下;

    参数

    -XX:+UseParallelOldGC:指定使用Parallel Old收集器;

    6、CMS(Concurrent Mark Sweep)收集器

    概述

    CMS是HotSpot在JDK5推出的第一款真正意义上的并发(Concurrent)收集器,第一次实现了让垃圾收集线程与用户线程(基本上)同时工作;

    命名中用的是concurrent,而不是parallel,说明这个收集器是有与工作执行并发的能力的。MS则说明算法用的是Mark Sweep算法。

    它关注的是垃圾回收最短的停顿时间(低停顿),在老年代并不频繁GC的场景下,是比较适用的。

    特点

    针对老年代

    标记-清除算法 (不进行压缩操作,产生内存碎片);

    并发

    多线程

    收集过程中不需要暂停用户线程

    以获取最短回收停顿时间为目标

    应用场景

    与用户交互较多的场景。CMS 收集器是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java应用集中在互联网或者B/S系统的服务端上,这类应用尤其注重服务的响应速度,希望系统停顿时间最短,以给用户带来极好的体验。CMS收集器就非常符合这类应用的需求。

    CMS是一种以获取最短回收停顿时间为目标的收集器。在重视响应速度和用户体验的应用中,CMS应用很多。

    CMS GC过程分四步完成:

    ae5a11b458e117b8f30fdc064821647c.png

    比前面几种收集器更复杂,可以分为4个步骤:

    1、初始标记(initial mark)

    单线程执行

    需要“Stop The World”

    但仅仅把GC Roots的直接关联可达的对象给标记一下,由于直接关联对象比较小,所以这里的速度非常快

    2、并发标记(concurrent mark)

    对于初始标记过程所标记的初始标记对象,进行并发追踪标记,

    此时其他线程仍可以继续工作。

    此处时间较长,但不停顿。

    并不能保证可以标记出所有的存活对象;

    3、重新标记(remark)

    在并发标记的过程中,由于可能还会产生新的垃圾,所以此时需要重新标记新产生的垃圾。

    此处执行并行标记,与用户线程不并发,所以依然是“Stop The World”,

    且停顿时间比初始标记稍长,但远比并发标记短。

    4、并发清除(concurrent sweep)

    并发清除之前所标记的垃圾。

    其他用户线程仍可以工作,不需要停顿。

    Tips:其中,初始标记和并发标记仍然需要Stop the World、初始标记仅仅标记一下GC Roots能直接关联到的对象,速度很快,并发标记就是进行GC RootsTracing的过程,而重新标记阶段则是为了修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段长,但远比并发标记的时间短。

    由于整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,所以整体上说,CMS收集器的内存回收过程是与用户线程一共并发执行的。

    参数

    -XX:+UseConcMarkSweepGC:使用CMS收集器

    -XX:+ UseCMSCompactAtFullCollection:Full GC后,进行一次碎片整理;整理过程是独占的,会引起停顿时间变长

    -XX:+CMSFullGCsBeforeCompaction:设置进行几次Full GC后,进行一次碎片整理

    -XX:ParallelCMSThreads:设定CMS的线程数量(一般情况约等于可用CPU数量)

    缺点

    总体来看,与Parallel Old垃圾收集器相比,CMS减少了执行老年代垃圾收集时应用暂停的时间;

    但却增加了新生代垃圾收集时应用暂停的时间、降低了吞吐量而且需要占用更大的堆空间;

    由于最耗费时间的并发标记与并发清除阶段都不需要暂停工作,所以整体的回收是低停顿的。

    由于CMS以上特性,缺点也是比较明显的,

    1、对CPU资源非常敏感

    对CPU资源非常敏感 其实,面向并发设计的程序都对CPU资源比较敏感。

    在并发阶段,它虽然不会导致用户线程停顿,但会因为占用了一部分线程(或者说CPU资源)而导致应用程序变慢,总吞吐量会降低。

    CMS默认启动的回收线程数是(CPU数量+3)/4,也就是当CPU在4个以上时,并发回收时垃圾收集线程不少于25%的CPU资源,并且随着CPU数量的增加而下降。

    但是当CPU不足4个时(比如2个),CMS对用户程序的影响就可能变得很大,如果本来CPU负载就比较大,还要分出一半的运算能力去执行收集器线程,就可能导致用户程序的执行速度忽然降低了50%,其实也让人无法接受。

    并发收集虽然不会暂停用户线程,但因为占用一部分CPU资源,还是会导致应用程序变慢,总吞吐量降低。

    CMS的默认收集线程数量是=(CPU数量+3)/4;

    当CPU数量多于4个,收集线程占用的CPU资源多于25%,对用户程序影响可能较大;不足4个时,影响更大,可能无法接受。

    2、浮动垃圾(Floating Garbage)

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

    由于在垃圾收集阶段用户线程还需要运行,那就还需要预留有足够的内存空间给用户线程使用,因此CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集,也可以热为CMS所需要的空间比其他垃圾收集器大;

    "-XX:CMSInitiatingOccupancyFraction":设置CMS预留内存空间;

    JDK1.5默认值为68%;

    JDK1.6变为大约92%;

    3、"Concurrent Mode Failure"失败

    如果CMS运行期间预留的内存无法满足程序需要,就会出现一次“Concurrent Mode Failure”失败,这时虚拟机将启动后备预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样会导致另一次Full GC的产生。这样停顿时间就更长了,代价会更大,所以 "-XX:CMSInitiatingOccupancyFraction"不能设置得太大。

    4、产生大量内存碎片

    这个问题并不是CMS的问题,而是算法的问题。由于CMS基于"标记-清除"算法,清除后不进行压缩操作,所以会产生碎片

    "标记-清除"算法介绍时曾说过:

    产生大量不连续的内存碎片会导致分配大内存对象时,无法找到足够的连续内存,从而需要提前触发另一次Full GC动作。

    4.1碎片解决方法:

    (1)、"-XX:+UseCMSCompactAtFullCollection"

    使得CMS出现上面这种情况时不进行Full GC,而开启内存碎片的合并整理过程;

    但合并整理过程无法并发,停顿时间会变长;

    默认开启(但不会进行,结合下面的CMSFullGCsBeforeCompaction);

    (2)、"-XX:+CMSFullGCsBeforeCompaction"

    设置执行多少次不压缩的Full GC后,来一次压缩整理;

    为减少合并整理过程的停顿时间;

    默认为0,也就是说每次都执行Full GC,不会进行压缩整理;

    由于空间不再连续,CMS需要使用可用"空闲列表"内存分配方式,这比简单实用"碰撞指针"分配内存消耗大;

    7、G1收集器

    概述

    G1(Garbage - First)名称的由来是G1跟踪各个Region里面的垃圾堆的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。

    G1(Garbage-First)是JDK7-u4才推出商用的收集器;

    注意:G1与前面的垃圾收集器有很大不同,它把新生代、老年代的划分取消了!

    这样我们再也不用单独的空间对每个代进行设置了,不用担心每个代内存是否足够。

    456243e67c19824c761c86b889f3d30e.png

    取而代之的是,G1算法将堆划分为若干个区域(Region),它仍然属于分代收集器。不过,这些区域的一部分包含新生代,新生代的垃圾收集依然采用暂停所有应用线程的方式,将存活对象拷贝到老年代或者Survivor空间。老年代也分成很多区域,G1收集器通过将对象从一个区域复制到另外一个区域,完成了清理工作。这就意味着,在正常的处理过程中,G1完成了堆的压缩(至少是部分堆的压缩),这样也就不会有CMS内存碎片问题的存在了。

    d278aed530716ea4981a02fb8590c946.png

    在G1中,还有一种特殊的区域,叫Humongous区域。 如果一个对象占用的空间超过了分区容量50%以上,G1收集器就认为这是一个巨型对象。这些巨型对象,默认直接会被分配在年老代,但是如果它是一个短期存在的巨型对象,就会对垃圾收集器造成负面影响。为了解决这个问题,G1划分了一个Humongous区,它用来专门存放巨型对象。如果一个H区装不下一个巨型对象,那么G1会寻找连续的H分区来存储。为了能找到连续的H区,有时候不得不启动Full GC。

    PS:在java 8中,持久代也移动到了普通的堆内存空间中,改为元空间。

    特点

    G1除了降低停顿外,还能建立可预测的停顿时间模型;

    1、Region概念

    横跨整个堆内存

    在G1之前的其他收集器进行收集的范围都是整个新生代或者老生代,而G1不再是这样。

    G1在使用时,Java堆的内存布局与其他收集器有很大区别,

    它将整个Java堆划分为多个大小相等的独立区域(Region),

    虽然还保留新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,而都是一部分Region(可以不连续)的集合。

    2、可并行,可并发

    能充分利用多CPU、多核环境下的硬件优势;

    G1 能充分利用多CPU、多核环境下的硬件优势,使用多个CPU来缩短“Stop The World”停顿时间

    并行:使用多个CPU来缩短Stop-The-World停顿的时间,

    并发:也可以并发让垃圾收集与用户程序同时进行

    3、分代收集,收集范围包括新生代和老年代

    能独立管理整个GC堆(新生代和老年代),而不需要与其他收集器搭配;

    能够采用不同方式处理不同时期的对象;

    4、空间整合,不产生碎片

    从整体看,是基于标记-整理算法;

    从局部(两个Region间)看,是基于复制算法;

    都不会产生内存碎片,有利于长时间运行;

    这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。

    5、可预测的停顿:低停顿的同时实现高吞吐量

    G1收集器之所以能建立可预测的停顿时间模型,是因为它可以有计划地避免在整个Java堆中进行全区域的垃圾收集。

    G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,

    每次根据允许的收集时间,优先回收价值最大的Region,这样就保证了在有限的时间内尽可能提高效率。(这也就是Garbage-First名称的来由)。

    这种使用Region划分内存空间以及有优先级的区域回收方式,保证了G1收集器在有限的时间内可以获取尽可能高的收集效率。

    应用场景

    如果你的应用追求低停顿,那G1现在已经可以作为一个可尝试选择,如果你的应用追求吞吐量,那G1并不会为你带来什么特别的好处。

    1.面向服务端应用,针对具有大内存、多处理器的机器;最主要的应用是为需要低GC延迟,并具有大堆的应用程序提供解决方案;

    如:在堆大小约6GB或更大时,可预测的暂停时间可以低于0.5秒;

    2.用来替换掉JDK1.5的CMS收集器;

    (1)、超过50%的Java堆被活动数据占用;

    (2)、对象分配频率或年代提升频率变化很大;

    (3)、GC停顿时间过长(长与0.5至1秒)。

    参数

    "-XX:+UseG1GC":指定使用G1收集器;

    "-XX:InitiatingHeapOccupancyPercent":当整个Java堆的占用率达到参数值时,开始并发标记阶段;默认为45;

    "-XX:MaxGCPauseMillis":为G1设置暂停时间目标,默认值为200毫秒;

    "-XX:G1HeapRegionSize":设置每个Region大小,范围1MB到32MB;目标是在最小Java堆时可以拥有约2048个Region;

    为什么G1收集器可以实现可预测的停顿?

    G1可以建立可预测的停顿时间模型,是因为:

    可以有计划地避免在Java堆的进行全区域的垃圾收集;

    G1跟踪各个Region获得其收集价值大小,在后台维护一个优先列表;

    每次根据允许的收集时间,优先回收价值最大的Region(名称Garbage-First的由来);

    这就保证了在有限的时间内可以获取尽可能高的收集效率;

    G1收集器运作过程

    b03dfc84f0de89fe474936cbd70aef32.png

    不计算维护Remembered Set的操作,可以分为4个步骤(与CMS较为相似)。

    1、初始标记(Initial Marking)

    初始标记仅仅只是标记一下GC Roots能直接关联到的对象,

    速度很快,

    需要“Stop The World”。(OopMap)

    2、并发标记(Concurrent Marking)

    进行GC Roots Tracing的过程,从刚才产生的集合中标记出存活对象;(也就是从GC Roots 开始对堆进行可达性分析,找出存活对象。)

    耗时较长,但应用程序也在运行;

    并不能保证可以标记出所有的存活对象;

    3、最终标记(Final Marking)

    最终标记和CMS的重新标记阶段一样,也是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,

    这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短,

    也需要“Stop The World”。(修正Remebered Set)

    4、筛选回收(Live Data Counting and Evacuation)

    首先排序各个Region的回收价值和成本;

    然后根据用户期望的GC停顿时间来制定回收计划;

    最后按计划回收一些价值高的Region中垃圾对象;

    回收时采用"复制"算法,从一个或多个Region复制存活对象到堆上的另一个空的Region,并且在此过程中压缩和释放内存;

    可以并发进行,降低停顿时间,并增加吞吐量;

    参数

    "-XX:+UseG1GC":指定使用G1收集器;

    "-XX:InitiatingHeapOccupancyPercent":当整个Java堆的占用率达到参数值时,开始并发标记阶段;默认为45;

    "-XX:MaxGCPauseMillis":为G1设置暂停时间目标,默认值为200毫秒;

    "-XX:G1HeapRegionSize":设置每个Region大小,范围1MB到32MB;目标是在最小Java堆时可以拥有约2048个

    总结

    8d9b5b42d191a4ad452074f204507378.png

    图中展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。

    虚拟机所处的区域,则表示它是属于新生代收集器还是老年代收集器。

    收集器总结

    收集器

    串行、并行or并发

    新生代/老年代

    算法

    目标

    适用场景

    Serial

    串行

    新生代

    复制算法

    响应速度优先

    单CPU环境下的Client模式

    Serial Old

    串行

    老年代

    标记-整理

    响应速度优先

    单CPU环境下的Client模式、CMS的后备预案

    ParNew

    并行

    新生代

    复制算法

    响应速度优先

    多CPU环境时在Server模式下与CMS配合

    Parallel Scavenge

    并行

    新生代

    复制算法

    吞吐量优先

    在后台运算而不需要太多交互的任务

    Parallel Old

    并行

    老年代

    标记-整理

    吞吐量优先

    在后台运算而不需要太多交互的任务

    CMS

    并发

    老年代

    标记-清除

    响应速度优先

    集中在互联网站或B/S系统服务端上的Java应用

    G1

    并发

    both

    标记-整理+复制算法

    响应速度优先

    面向服务端应用,将来替换CMS

    参数总结

    参数

    MinorGC

    Full GC

    描述

    -XX:+UseSerialGC

    Serial收集器串行回收

    Serial Old收集器串行回收

    该选项可以手动指定Serial收集器+Serial Old收集器组合执行内存回收

    -XX:+UseParNewGC

    ParNew收集器并行回收

    Serial Old收集器串行回收

    该选项可以手动指定ParNew收集器+Serilal Old组合执行内存回收

    -XX:+UseParallelGC

    Parallel收集器并行回收

    Serial Old收集器串行回收

    该选项可以手动指定Parallel收集器+Serial Old收集器组合执行内存回收

    -XX:+UseParallelOldGC

    Parallel收集器并行回收

    Parallel Old收集器并行回收

    该选项可以手动指定Parallel收集器+Parallel Old收集器组合执行内存回收

    -XX:+UseConcMarkSweepGC

    ParNew收集器并行回收

    缺省使用CMS收集器并发回收,备用采用Serial Old收集器串行回收

    该选项可以手动指定ParNew收集器+CMS收集器+Serial Old收集器组合执行内存回收。优先使用ParNew收集器+CMS收集器的组合,当出现ConcurrentMode Fail或者Promotion Failed时,则采用ParNew收集器+Serial Old收集器的组合

    -XX:+UseConcMarkSweepGC

    -XX:-UseParNewGC

    Serial收集器串行回收

    -XX:+UseG1GC

    G1收集器并发、并行执行内存回收

    暂无

    ZGC

    概述

    在JDK 11当中,加入了实验性质的ZGC。它的回收耗时平均不到2毫秒。它是一款低停顿高并发的收集器。

    ZGC几乎在所有地方并发执行的,除了初始标记的是STW的。所以停顿时间几乎就耗费在初始标记上,这部分的实际是非常少的。那么其他阶段是怎么做到可以并发执行的呢?

    ZGC主要新增了两项技术,一个是着色指针Colored Pointer,另一个是读屏障Load Barrier。

    ZGC 是一个并发、基于区域(region)、增量式压缩的收集器。Stop-The-World 阶段只会在根对象扫描(root scanning)阶段发生,这样的话 GC 暂停时间并不会随着堆和存活对象的数量而增加。

    ZGC 的设计目标

    TB 级别的堆内存管理;

    最大 GC Pause 不高于 10ms;

    最大的吞吐率(Throughput)损耗不高于 15%;

    关键点:GC Pause 不会随着 堆大小的增加 而增大。

    ZGC 中关键技术

    加载屏障(Load barriers)技术;

    有色对象指针(Colored pointers);

    单一分代内存管理(这一点很有意思);

    基于区域的内存管理;

    部分内存压缩;

    即时内存复用。

    并行化处理阶段

    标记(Marking);

    重定位(Relocation)/压缩(Compaction);

    重新分配集的选择(Relocation set selection);

    引用处理(Reference processing);

    弱引用的清理(WeakRefs Cleaning);

    字符串常量池(String Table)和符号表(Symbol Table)的清理;

    类卸载(Class unloading)。

    着色指针Colored Pointer

    ZGC利用指针的64位中的几位表示Finalizable、Remapped、Marked1、Marked0(ZGC仅支持64位平台),以标记该指向内存的存储状态。相当于在对象的指针上标注了对象的信息。注意,这里的指针相当于Java术语当中的引用。

    在这个被指向的内存发生变化的时候(内存在Compact被移动时),颜色就会发生变化。

    在G1的时候就说到过,Compact阶段是需要STW,否则会影响用户线程执行。那么怎么解决这个问题呢?

    读屏障Load Barrier

    由于着色指针的存在,在程序运行时访问对象的时候,可以轻易知道对象在内存的存储状态(通过指针访问对象),若请求读的内存在被着色了,那么则会触发读屏障。读屏障会更新指针再返回结果,此过程有一定的耗费,从而达到与用户线程并发的效果。

    把这两项技术联合下理解,引用R大(RednaxelaFX)的话

    与标记对象的传统算法相比,ZGC在指针上做标记,在访问指针时加入Load Barrier(读屏障),比如当对象正被GC移动,指针上的颜色就会不对,这个屏障就会先把指针更新为有效地址再返回,也就是,永远只有单个对象读取时有概率被减速,而不存在为了保持应用与GC一致而粗暴整体的Stop The World。

    ZGC虽然目前还在JDK 11还在实验阶段,但由于算法与思想是一个非常大的提升,相信在未来不久会成为主流的GC收集器使用。

    参数

    ZGC回收机预计在jdk11支持,ZGC目前仅适用于Linux / x64 。和G1开启很像,用下面参数即可开启:

    -XX:+UnlockExperimentalVMOptions -XX:+UseZGC

    参考

    展开全文
  • 被动信息收集

    千次阅读 2021-11-13 17:08:29
    被动信息收集概述和目的 信息收集的方式分为两种:被动和主动。 被动信息收集方式是指利用第三方的服务对目标进行了解,如:Google搜索。 主动的信息收集方式:通过直接访问、扫描网站,这种将流量流经网站的...
  • CMS垃圾收集算法分代收集理论标记-复制算法标记-清除算法标记-整理算法垃圾收集器Serial收集器(-XX:+UseSerialGC -XX:+UseSerialOldGC)Parallel Scavenge收集器(-XX:+UseParallelGC(年轻代),-XX:+UseParallelOldGC...
  • 常用信息收集方法

    千次阅读 2021-09-07 10:22:29
    信息收集的种类 信息收集分为被动收集和主动收集两种方式。 被动信息收集:利用第三方的服务对目标进行访问:Google搜索、Shodan搜索、其他综合工具,被动信息收集是指京可能多低收集与目标相关的信息 主动信息收集...
  • 域信息收集

    千次阅读 2021-04-02 23:23:16
    进入内网后首先要进行信息收集,判断当前所处环境的一些情况 一. 判断当前用户是本地用户还是域用户 在命令行中,输入hostname查看主机名。接着再输入whoami查看当前身份 本地用户 如果是本地用户d 域用户 ...
  • Jvm 垃圾收集

    2021-11-09 16:50:28
    垃圾收集算法:为实现垃圾回收提供理论支持 垃圾收集器:利用垃圾收集算法,实现垃圾回收的实践落地。 各种垃圾收集器之间也是可以配合使用的: 比如 CMS可以和ParNew配合,CMS和Parallele Scavenge 不能使用 ...
  • 分代收集理论标记-复制算法标记-清除算法标记-整理算法垃圾收集器1.Serial收集器2.Parallel Scavenge收集器3.ParNew收集器4.CMS收集器CMS的相关核心参数三色标记法多标-浮动垃圾漏标-读写屏障写屏障写屏障实现SATB写...
  • 摘 要:信息技术的发展,很多传统人工手动完成的任务逐渐由计算机信息技术所替代,在数据收集方面,手动收集、输入数据早已被社会所淘汰,机器收集数据是科学技术发展的必然结果。现代机器数据收集,计算机发挥着...
  • CMS收集器是一个里程碑式的收集器,之前的收集器都是并行收集器,从CMS收集器开始后的都是并发收集器,但是CMS的缺点非常多,以至于所有的JDK版本没有一个将CMS收集器设置为默认的收集器。 长期来看,CMS收集器是要...
  • 在线表单收集系统Tduck(docker篇)

    千次阅读 2021-11-01 00:07:13
    在线表单收集系统Tduck(上篇) 在线表单收集系统Tduck(下篇) 没有找到官方的镜像,不过你可以试试???? 这是一个多合一的镜像,用于体验还是可以的,安装说明可以在参考文档部分找到,但是似乎并不支持设置自己...
  • 内网渗透之域内信息收集

    千次阅读 2021-10-01 00:18:29
    当获取了一台在域内的Windows服务器权限,就需要我们尽可能地去收集所能获取到的域的相关信息,收集的域的信息越多,拿下域控的成功率越高。01、判断是否存在域(1)一般我们在进行本机信息收...
  • 文章目录一、个人信息的收集1、收集个人信息的合法性2、收集个人信息的最小必要3、多项业务功能的自主选择4、收集个人信息时的授权同意5、个人信息保护政策6、征得授权同意的例外二、个人信息的存储1、个人信息存储...
  • 1.1. Serial收集器 1.2. ParNew收集器 1.3. Parallel Scavenge收集器 1.4. Serial Old收集器 1.5. Parallel Old收集器 1.6. CMS收集器 1.7. G1收集器 1.8. 总结 1.9. 垃圾收集器参数汇总 1. jvm垃圾回收器 本篇...
  • CTF 题目信息收集

    2020-12-22 15:09:27
    CTF 题目信息收集信息收集分类敏感目录泄露git泄露 信息收集 在线上CTF比赛Web类题目中,信息收集涵盖的面非常广,同时非常重要。 分类 敏感目录泄露 通过泄露的敏感目录,可以获取网站的源代码和敏感的URL地址,如...
  • 依赖收集 讲依赖收集之前我们需要先了解三个点: Observe类:用于将响应式对象的属性转换成可以被检测的属性(为其属性添加getter和setter) Dep类:用于收集当前响应式对象的依赖 Watcher类:作为一个中介(观察者...
  • mysql收集统计信息

    2021-01-18 21:34:27
    一、手动执行Analyze tableinnodb和myisam存储引擎都可以通过执行“Analyze table tablename”来收集表的统计信息,除非执行计划不准确,否则不要轻易执行该操作,如果是很大的表该操作会影响表的性能。二、自动触发...
  • CMS与G1垃圾收集器详解

    千次阅读 2021-10-24 20:09:48
    CMS 收集器 CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户交互体验的应用上使用.CMS 收集器是 HotSpot 虚拟机第一款真正意义上的并发收集器,它第一次实现...
  • CMS垃圾收集器与三色标记算法详解 目录 CMS垃圾收集器详解 垃圾收集器前世今生 CMS垃圾收集器原理 三色标记算法 垃圾收集器的前世今生 现代垃圾收集器都是基于分代收集理论,将java对象按年龄分为...
  • 本章讲述自动化信息收集工具nmapAutomator。该工具将很多信息收集工具进行集成,自动全面的帮助attacker收集目标信息。 1.场景 虚拟机:vmware 攻击主机:kali IP:192.168.239.142 靶机:Windows10 IP:192.168.239.1...
  • 信息收集(部分,不全面)

    千次阅读 2020-12-23 08:41:00
    文章目录信息收集第一部分:被动信息收集1、简介2、信息收集的内容3、信息收集的用途4、二级域名或IP收集1).DNS信息收集利用nslookup利用dig2).DNS域传送漏洞利用dig利用host利用dnsenum3).备案号查询4).SSL查询5)....
  • java垃圾回收G1收集

    2021-03-18 12:20:20
    G1(Garbage First)收集器是当今收集器技术发展的最前沿成果之一,他是一款面向服务端的垃圾收集器,它的使命是(在比较长期的)未来可以替换掉CMS收集器。它的特点如下:1、并行与并发:G1能充分利用多CPU、多核环境下...
  • 一、何为G1收集器 The Garbage-First (G1) garbage collector is a server-style garbage collector, targeted for multiprocessor machines with large memories. It attempts to meet garbage collection (GC) ...
  • 渗透测试之信息收集

    2020-12-20 16:47:06
    渗透之信息收集 信息收集主要是收集服务器的配置信息和网站的敏感信息,主要包括域名信息、子域名信息、目标网站信息、目标网站真实IP、目录文件、开放端口和服务、中间件信息、脚本语言等等等 当你拿到一个目标站,...
  • Loki搭建日志收集系统

    2021-03-16 11:39:14
    Loki 什么是Loki Loki是受Prometheus启发的...类似elk中的logstash、filebeat等,如果收集docker容器日志的话可以用docker插件来收集容器日志 获取软件包并解压 配置pormtail配置文件 vim promtail.yaml --- server: ...
  • Github信息收集骚姿势

    千次阅读 2021-11-26 11:41:54
    目录 一、github搜索之基础语法 二、配合google语法使用 ...如何使用高级命令语法进行信息收集让你我有意想不到的收获呢? 一、github搜索之基础语法 in:name test # 仓库标题搜索含有关键字test language:java...
  • 资产收集的方法总结

    2021-02-01 16:49:23
    很多人以为资产收集就是信息收集,刚开始我也是这样认为的,其实信息收集包含资产收集但不限于资产收集,信息收集包含whois,真实IP,网站架构,子域名收集,敏感目录,DNS信息,旁站,C段,端口等;而资产收集主要...
  • 今天来详细解释Vue 收集表单的数据,说到数据我们就想到要使用v-model ,双向数据绑定,技能收集用户输入数据,又能想页面传入数据 那么我们下面就来做一个简单的表单介绍vue是如何收集数据的 1.首先我们使用html...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,261,883
精华内容 504,753
关键字:

收集