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

网站页脚设计win2008iis7配置网站

网站页脚设计,win2008iis7配置网站,wordpress符号,怎么看一个网站是不是外包做的大纲 1.G1的FGC可以优化的点 2.一个bug导致的FGC(Kafka发送重试 subList导致List越来越大) 3.为什么G1的FGC比ParNew CMS要更严重 4.FGC的一些参数及优化思路 1.G1的FGC可以优化的点 (1)FGC的基本原理 (2)遇到FGC应该怎么处理 (3)应该如何操作来规避FGC (4)应该如何操…大纲 1.G1的FGC可以优化的点 2.一个bug导致的FGC(Kafka发送重试 subList导致List越来越大) 3.为什么G1的FGC比ParNew CMS要更严重 4.FGC的一些参数及优化思路 1.G1的FGC可以优化的点 (1)FGC的基本原理 (2)遇到FGC应该怎么处理 (3)应该如何操作来规避FGC (4)应该如何操作来加快FGC的速度 (1)FGC的基本原理 一.FGC的并行处理 G1有两个得天独厚的优势 优势一.Region是一个相对独立的内存区域 优势二.每个Region都有一个RSet 通过GC Roots  RSet就能完整对某Region进行所有存活对象的标记。 二.FGC的并行处理流程 并行FGC开始前的前置工作对象头、锁信息等信息的保存处理。在保存完一些对象头相关的信息之后就要开始FGC了。 具体步骤和串行化的FGC是类似的。 步骤一标记所有存活对象 步骤二计算对象的新地址 步骤三更新对象间的引用地址 步骤四移动对象完成压缩 步骤五对象移动后的后续处理 三.并行标记过程STW FGC并行化后其并行标记过程和串行化过程时差别不是很大都是要标记出来所有的存活的对象。 需要注意的是因为是并行化处理所以多个线程在进行并行标记时每个线程都会比起串行化处理时多一个标记栈(任务栈)。也就是把起始对象GC Roots分成多份每一个GC线程持有一部分。 FGC会对所有堆分区里的对象都进行标记而且系统程序会STW。 四.FGC标记过程中的任务窃取 完成任务栈的对象标记的线程会从未完成的线程那里窃取一些任务。 (2)遇到FGC应该怎么处理 一.尽可能避免 FGC是需要极力避免的JVM的优化手段多数都是尽可能减少FGC的出现。比如调整分代比例、Region大小、停顿时间、老年代预留空间比例等。所以对于FGC的处理最重要的手段就是避免它。 二.尝试优化FGC的速率 如果是正常的FGC优化速率的方法就是减少FGC需要处理的量。也就是FGC时避免堆中存在大量需要复杂处理的对象。 (3)应该如何操作来规避FGC 基本的思路还是要避免达到产生FGC的条件。 一.产生FGC的条件主要是以下两种 条件一MGC不及时导致垃圾对象存活过多造成空间不够 这其实也是并发标记的启动时机存在问题。如果并发标记启动的频率远远落后于垃圾产生的速率。那么就会出现大量空间被垃圾对象占用导致不必要的FGC。另外就是回收速度太低导致停顿时间内回收垃圾太少造成空间不够。 条件二存活对象太多各种GC都尝试过无法腾出足够空间给新对象 执行了YGC MGC后出现晋升失败不得不进行FGC。 二.产生FGC的场景主要是以下两种 场景一G1使用的算法是标记复制算法(YGC和MGC)  标记整理算法(FGC)。在进行垃圾回收时新创建的对象及存活的对象没有足够空间可使用。复制操作无法实现因为每次GC的存活对象要复制到空闲Region中。 场景二多次GC后仍然无法给新对象腾出足够的空间导致FGC。此时所能做的就是尽可能合理优化参数保证不触发这些场景。 (4)应该如何操作来加快FGC的速度 FGC的速度在JVM层面其实已经做了很多优化包括并行优化等。那么在此基础之上我们还能通过什么策略来提升FGC的速度比如要减少FGC处理的总量靠减少堆内存来减少FGC要处理的总量吗针对FGC的速度要做的优化不能简单的从堆内存空间大小来考虑。 G1提供了一种思路叫弥留空间。当G1发现经历多次GC后就会允许一定比例的空间作为把垃圾对象当成存活对象处理的空间。这些垃圾对象所在的一定范围的区域可以成为弥留空间。虽然这个弥留空间是垃圾对象但在GC处理时是当作存活对象来处理。 FGC在处理这块弥留空间里的对象时会把它们直接当作存活对象来处理不需要做各种复杂的标记、判定引用、指针替换等各种操作直接去复制。明知是死亡对象但此时先不做全部空间的标记压缩整理而只做部分的。所以弥留空间就能快速被跳过减少处理空间一定程度提高FGC的速率。弥留空间就是为了提升FGC的效率而设计的。 2.一个bug导致的FGC(Kafka发送重试 subList导致List越来越大) (1)运营场景业务分析 (2)业务场景背景介绍 (3)问题现场及问题排查 (4)问题解决 (1)运营场景业务分析 一般在电商公司里会有一个运营平台有些公司叫营销平台这个平台的作用主要就是拉新、增涨营收。就是通过运营平台发起活动、或者投放广告来实现用户增长。对于平台的存量用户也会有优惠活动、节日福利活动等来留住用户。 各种各演的运营活动都会通过运营平台去产生。然后专门有一个抽离的运营消息推送服务来推送运营活动消息给用户。由于这些消息的数量非常庞大对于一家几十万上百万的用户一天假如有3次运营活动就要至少好几百万甚至上千万的的消息要推送。这么大量的消息不会直接全量推送而是生成推送消息发送到MQ然后通过一个消费者去消费这些消息慢慢把千万级别的消息推送给用户。 (2)业务场景背景介绍 在这个场景中一个很重要的要点就是运营消息推送平台会生成消息推送到消息中间件Kafka中。这个消息生成、推送至MQ的速率很大程度影响到整个推送流程的速度。 因此对这个消息生成和推送的过程就需做优化当时优化的思路是 一.分布式生成消息即多台机器把用户群体分成多个部分来生成消息 二.batch推送消息减少与消息中间件的网络通信 三.运营消息推送平台使用多线程并发推送batch消息 四.把一些大批量的查询借助一些其他的数据搜索引擎或缓存来提升效率 比如借助JVM本地缓存每台机器保存一些用户账号相关信息。比如使用ES来存储用户信息提升多条件下的搜索查询效率。比如使用Redis Cluster缓存避免使用数据库导致效率低。 这些基本的思路其实还是比较简单的细节上的优化就是batch的大小如何确定、多线程推送时线程池的线程数量要怎么设置等。 (3)问题现场及问题排查 一.引发OOM的原因是频繁FGC 然后在一次优化测试上线后运行一段时间没有什么大问题。在某天Kafka服务发生了一次抖动持续时间大概5-6s的时间然后发现这个运营平台直接崩溃了。 在优化前这个运营平台的推送效率有待提升但是系统还是很稳定的。出现这个问题后紧急查看了报错日志发现是堆内存OOM导致进程崩溃。 于是下载GC日志下载内存快照文件查看dump快照文件最后发现是batch推送时线程池中的线程持有了大量的大List对象。 本来是打算找OOM的原因解决OOM问题的。但发现在OOM前出现了大量的FGC而大量的FGC才最终导致系统崩溃。 那么结合dump快照里大量的List对象很容易想到是大量的List导致频繁FGC。而大量的List都还存活所以最终导致OOM。 二.频繁FGC的原因是List造成的对象过大 那么为什么会有这么多次FGC为什么有这么多的List没被回收通过代码排查发现了一个很严重的代码bug这个bug其实很好规避。 原来在代码中采取的策略是每次会查询一组用户数据这组用户数据会有2000个用户。然后将这组数据封装成消息体是按照一个List放200个用户去封装也就是将200个用户封装成一个List消息体之后才会发送到Kafka中。 注意Kafka本身也有一个缓冲机制来实现batch发送。我们的代码将消息一条一条发送时Kafka会在本地客户端暂存。存到一定大小时才会按照一个批次推送到Kafka服务端。 这种策略正常来说是没问题的因为200个用户封装后的大小也不大。但是写代码时因为运营的一个需求把其中一段代码修改了一下。运营要求在某个促销活动下消息必须推送到用户侧不能出现漏发错发多发。 原有的代码是把拿到的2000一组的用户数据拆分成10个batch然后推送至Kafka。假如推送失败就不管了因为漏发某个用户的消息也问题不大。 修改后的代码是针对这种特殊活动添加了一些逻辑即等待Kafka返回推送结果。如果拿到推送结果则表明推送成功则执行完毕。如果拿不到推送结果则表明推送失败需要把失败的用户集重新加入到一个集合中去重试推送。具体的伪代码如下 //获取一组用户信息ArrayList list getUserList();List subList;List failList new ArrayList();int index  0;//拆分用户信息while(true) {    if (index  list.size()-1) {        break;    }    subList list.subList(index, index  200);    kafkaPushResult sendToKafka();    //等待发送结果    if (kafkaPushResult false) {        //发送失败是第一次就把发送失败的subList赋值给failList        if (index  0) {            failList subList;        }        //不是第一次就把发送失败的全部加入到failList中等待后续继续发送        failList.addAll(subList);    }} 上述代码看起来是不是没什么问题事实上当这个kafkaPushResult失败没有触发时确实不会出什么问题。但是一旦触发了失败就会出现问题了。 原因在于对于List来说subList不是新建了一个对象而是把大的list的其中一段使用了两个指针去指向它所以本质上subList还是大的list的一部分。 那么如果频繁触发发送失败failList这么写就相当于是大的list的一部分。那么执行failList.addAll(subList)代码时相当于是在把这部分失败的元素加入到大的list里。 所以list是会越来越大。如果一次推送几十万用户的消息一个线程池里面设置30-60个线程。那么在Kafka抖动的几秒的这段时间这些list会极速扩张好几千倍不止。也就是说假设这5s内一共能拿到10w的用户数据。那么在5s内就会膨胀到几千万甚至上亿的数据紧接着重试操作会针对这些数据重试而这个大的list又暂时不释放。如果Kafka抖动时间短经历几次FGC就完成重新推送没什么问题了。如果Kafka经常抖动或抖动时间长就会造成频繁的FGC甚至OOM。 这个场景由于FGC产生的原因比较直接。所以分析时很容易通过GC日志 dump快照文件迅速定位了问题。但很多FGC场景产生的原因各不相同分析过程还是会非常复杂的。不过基本思路都是系统日志 - 监控数据 - GC日志 - dump文件 - 代码反查 - bug复现 - 解决问题。 (4)问题解决 知道了问题原因其实就很好解决了。根本原因还是因为在写代码时对api源码的实现不熟悉同时也没有深入检查代码的习惯导致在做一些业务处理时出现了意想不到的bug。 对于这个代码其实只需要做一个改动就OK了。在外层初始化failList并且在需要把subList数据作为数据源的操作时使用addAll操作把它加入到新的list中再进行操作即可。​​​​​​​ failList  new ArrayList(); if (index  0) {failList subList; }- failList.addAll(subList) 在使用subList拆分list时一定要熟悉一下这个subList的源码实现方式。往往JDK的一些优化手段会给我们程序造成一些不必要的问题。 此外如果出现了频繁FGC很有可能是对象产生的速度和垃圾回收的速度匹配不上回收的量不够就会有可能OOM了。 3.为什么G1的FGC比ParNew CMS要更严重 (1)ParNew CMS的FGC触发 (2)G1的FGC触发 (3)G1的FGC更加恐怖的原因总结 (1)ParNew CMS的FGC触发 ParNew CMS触发的FGC的规则其实还是比较简单的总结来说就是老年代不够用了。 当然老年代不够用的过程可能比较多新生代晋升、大对象占用等。但使用ParNew CMS时新生代和老年代的比例往往都是比较均衡有些系统新生代甚至远大于老年代。 那么在这种场景下FGC相对来说回收的空间就不算太恐怖毕竟回收的空间只有堆内存的1/2左右。比较耗时的地方就是全量标记、对象复制、压缩整理的过程。因此FGC即使偶尔发生一次比如一天一次或几小时一次也能接受。 并且老年代对象的晋升是有一系列的担保机制的比如老年代剩余内存大于新生代存活对象、老年代剩余内存大小大于历次新生代晋升到老年代的对象的平均大小等。 因此综合分析下来ParNew CMS触发FGC时从空间上和处理算法(标记整理)上来说偶尔一次还是能够接受的。 (2)G1的FGC触发 G1的FGC触发场景基本上有两种 一.新生代晋升失败导致的FGC 有可能是因为晋升预留空间不够导致的比如预留的晋升空间比例参数G1ReservePercent调整为了5而新生代区本次晋升对象比较多此时就会发生晋升失败导致FGC。 这种情况触发的FGC稍微好一点因为老年代的实际使用量是老年代大小 * (1  -  --XX:G1ReservePercent%)。并且因为是晋升导致的FGC此时新生代是刚执行完新生代回收的。所以基本上这种情况下导致的FGC只需回收相对比较小的区域即可。 即便如此这种情况下的FGC效率依然很低因为涉及到大量的标记、压缩、整理、引用处理等各种操作。 二.对象分配失败导致的FGC 对象分配失败导致的FGC就比较恐怖了。因为在对象分配失败时会经历如下整个过程TLAB - TLAB扩展 - 堆内存分配 - Region扩展 - YGC - MGC - 堆扩展 - 分配失败。 如果是这个过程造成分配失败则意味着整个堆内存的使用率非常高。即使经过了YGC MGC 扩展操作还是无法成功分配。 这时进入的FGC就可以理解为几乎大部分的内存都被占用了连一个对象都无法成功分配。此时的FGC需要处理的Region几乎是整个堆内存里的所有Region。 并且结合FGC的整个处理过程标记-对象头处理-对象移动-压缩-清理-Rset处理等一系列操作此时的FGC就会非常耗时。 所以这个情况下触发的FGC会非常恐怖当然如果没有乱调参数正常情况也不会发生这么恐怖的FGC。 三.总结 如果YGC执行后晋升失败导致FGC那么就是reserve空间不够导致的。也就是分配对象失败执行YGC后必然会发生晋升此时有可能就会在晋升失败前触发FGC来清理了。所以基本上不会出现达到多次YGC MGC之后还无法分配成功的情况。 但要注意有可能会出现QPS暴增对象产生速度比较快然后回收速度比较慢虽然经历了多次YGC但垃圾对象依然很多的情况。 (3)G1的FGC更加恐怖的原因总结 一.G1通常来说要管理更大的堆内存空间因此需要处理更多的对象 二.G1触发FGC的条件比较苛刻分配失败的FGC需处理整个堆内存 三.G1在执行FGC过程中需要针对复杂的Rset引用关系做更多处理 4.FGC的一些参数及优化思路(都围绕回收速度跟不上垃圾产生速度展开) (1)-XX:G1HeapRegionSize (2)-XX:G1ReservePercent默认是10 (3)-XX:MaxGCPauseMillis停顿时间 (4)-XX:InitiatingHeapOccupancyPercent (5)-XX:ConcGCThreads (6)-XX:G1ConcMarkStepDurationMillis (7)-XX:MarkSweepAlwaysCompactCount (1)-XX:G1HeapRegionSize 这个参数用于控制Region大小调整这个参数可以避免老年代中的大对象占用过多的内存。因为老年代大对象占用过多的内存就会提高老年代的使用率。老年代的使用率高了就必然会增加晋升失败的概率。所以增大Region大小可以避免不算太大的对象进入老年代从而降低晋升失败的概率。 调大RegionSize的另外一个优点是在发生对象复制、晋升时PLAB也会相对大一些从而在复制、晋升时速率也会提升。 (2)-XX:G1ReservePercent默认是10 这个参数代表老年代预留给新生代对象晋升的空间占用堆内存的比例如果经常因为晋升失败导致FGC说明这个值太小。此时可适当调高这个值降低FGC频率。 (3)-XX:MaxGCPauseMillis停顿时间 这个参数设置是否合理关系到了垃圾回收的效率。假如设置了20ms的停顿时间则很有可能导致每次GC回收的垃圾非常少。假如系统并发非常高产生垃圾的速度非常快就有可能会不断进行YGC。但是每次YGC都只能回收掉很少一部分垃圾最终造成FGC。 所以一个合理的停顿时间设置是非常有必要的。一般情况下系统的停顿时间可以设置100-200ms之间具体情况需要根据系统运行情况及JVM监控情况来调整。 (4)-XX:InitiatingHeapOccupancyPercent 意思是当堆内存的占用比例达45%时就会触发并发标记(可能开启MGC)。假如因为垃圾回收的速率跟不上系统产生垃圾的速度而造成频繁的FGC那么就可以适当调低这个参数尽快开启MGC通过提升MGC的频率来避免JVM内堆积过多的垃圾对象。 注意这个参数调小造成的多次GC和停顿时间造成的多次GC不是一个概念。 停顿时间造成的GC是因为每次停顿时间不够只能回收很少的垃圾导致垃圾堆积最终FGC。 调小InitiatingHeapOccupancyPercent这个参数此时停顿时间固定但是回收的频率提升上来了。这样在同样的程序运行时间里能够回收更多的垃圾可以避免FGC。 (5)-XX:ConcGCThreads 这个参数是指在标记过程中的并行标记(STW)线程数量。如果因为并发标记不够及时并发标记时间过长导致垃圾回收的速率跟不上造成FGC。 略微提升这个值可能能够提升标记速度以达到避免FGC的效果。当然线程数量多少要和服务器的配置相匹配不能盲目调大这个值。 (6)-XX:G1ConcMarkStepDurationMillis 这个参数指的是并发标记(不会STW)执行的时间默认是10ms。调小该参数可以提升并发标记的次数让并发标记触发的更加频繁一点从而让重新标记更短一点以此来提升垃圾回收的速率避免垃圾回收速度跟不上垃圾产生速度最终造成FGC。 正常来说这个参数也是不需要调整的只有发现系统经常因为垃圾处理不及时而频繁的触发FGC才有可能需要调小这个参数。 (7)-XX:MarkSweepAlwaysCompactCount 这个参数表示经过多次GC后允许JVM内存中有一定比例的空间用来将垃圾对象当作存活对象来处理可以称这块儿空间为弥留空间。 弥留空间主要的目的就是可以把垃圾对象当作存活对象来处理相当于给了一块比较好处理的空间能够减少FGC时的处理压力。可以说是间接减少FGC需要处理的空间这个空间不宜太大。如果太大就会造成一部分空间被占用一般来说保持默认即可。 (8)总结 上面介绍的这些参数多数都是以避免FGC的思路来展开优化。只有第七个参数是通过为FGC减负的思路来展开优化而且避免FGC通常都是从提升垃圾回收的速率这个角度出发让垃圾回收速率赶上垃圾对象产生的速率。 对于FGC来说减负这个思路在多数情况下是无法采取的。因为FGC的特性就决定了不太可能通过其本身的参数调整来提速更多的优化思路和优化手段还是要从避免角度出发避免大多数FGC才是优化的重点。 回收速度跟不上垃圾产生速度总结 一.调大RegionSize让PLAB增大从而加快复制、晋升的速度 二.调大老年代预留给新生代晋升的占比降低晋升失败的频率 三.调小触发MGC的老年代占比加快MGC 四.增加并发标记的线程加快GC 五.降低每次并发标记的执行时间降低重新标记时间加快GC 六.调大弥留空间占比降低FGC的处理压力提升FGC的处理速度 为什么G1的FGC比ParNew CMS要更严重 一.ParNew CMS的FGC触发 就是老年代不够用了。 二.G1的FGC触发条件 条件一新生代晋升失败导致的FGC。 条件二对象分配失败导致的FGC。 三.G1的FGC更加恐怖的原因总结 原因一G1通常来说要管理更大的堆内存空间因此需要处理更多的对象。 原因二G1触发FGC的条件比较苛刻分配失败的FGC需处理整个堆内存。 原因三G1在执行FGC过程中需要针对复杂的Rset引用关系做更多处理。
http://www.sczhlp.com/news/154990/

相关文章:

  • 贵阳高端网站设计公司wordpress滑动菜单
  • 二级学院网站建设自评报告网站忧化是干什么的
  • 音乐网站开发答辩ppt毕业设计网站选题
  • 中山创海软件网站建设成都建设门户网站
  • 长沙做黄叶和网站的公司有哪些织梦网站后台密码忘记了怎么做
  • 杭州设计 公司 网站建设多站点cms
  • 商务网站建设与维护 课件站长统计app
  • 青海专业的网站建设公司网站后台对接表
  • 安徽建设工程信息网固镇县下载班级优化大师并安装
  • 淘客网站模板网址生成app一键生成器
  • SQL 多表查询速查:JOIN、子查询一文全掌握 - 详解
  • 链表实现双端队列
  • 动手动脑实验性问题总结
  • 做的网站被注销一般建一个外贸网站多少钱
  • wordpress微网站模板模板做网站优缺点
  • 高质量网站外链建设大揭秘怎么做链接网站
  • 上海网站建设收费公司做营销网站
  • 网站建设易网wordpress充值漏洞
  • 信阳新网站做seo优化北京建设银行
  • 任何人任意做网站销售产品违法吗谷歌翻译做多语言网站
  • 企业网站接入微信支付中国空间站有几个舱段
  • wp网站开发做网站前的准备
  • 网站建设目标及需求分析wordpress 分类目录 菜单
  • 网站建设公司运营模式光伏项目建设背景
  • 有哪些是做二手的网站做网站骗老外的钱
  • 跑腿网站建设上海响应式网站建设推荐
  • 企业网站开发报价单成全视频免费观看在线看小说
  • 长沙做网站一般要多少钱苏州网站seo优化
  • 什么网站可以查建筑工程项目网站备案注销
  • 网站导航栏下载长葛哪里有做网站的