zoukankan      html  css  js  c++  java
  • 收录(一)

    https://www.cnblogs.com/QG-whz/p/9647614.html

    从一次线上故障思考Java问题定位思路

    for(int i = 1 ;i <= totalPage ;i++) {

    死循环

    top -p 12309 -H

    -p用于指定进程,-H用于获取每个线程的信息,从top输出的内容,可以看到有四个线程占用了非常高的CPU

    jstack -l 12309 > stack.log

    到这里可以确定的是,死循环引发了Full GC,四个GC线程一直尝试着回收内存,这四个线程将CPU占满。

    可以在机器上使用jmap命令来生成head dump文件。

    jmap -dump:live,format=b,file=headInfo.hprof 12309

    [导致fullgc]live这个参数表示我们需要抓取的是目前在生命周期内的内存对象,也就是说GC收不走的对象,在这种场景下,我们需要的就是这些内存的信息。[定位回收不了的对象]

     ============================ ============================

    https://mp.weixin.qq.com/s?__biz=MzIwMzY1OTU1NQ==&mid=2247484783&idx=2&sn=d22116d6e9562e15a240bded40383e22&chksm=96cd4523a1bacc35f7eacfcc3d3d4dcd13947d6d612d9299256dc50a47e2d868a4d302bc9fb0&mpshare=1&scene=1&srcid=1106kmea3JQ2rdWuYyK61iFS&key=2839d46a2ccd1adac7aa3a9a6970c1cc6735be3193586ce90637ba6853aa8e66daff3bffae10f71d27c5f83a5e1d06c589e0deabd215857f19bd0b3c56ee0fdd08e993e3ec3fdf2fee805bedfc8ec759&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=WkTrW9fz23LjFqzeh3GP9TDogP98DJkZiwfc%2BEMNGIg4KlsUSWFD%2B43qMoUBtM%2FM

    又发生频繁FGC,这次是谁的锅?

    CPU飙升——top -H -p 91782——jstack -l 91782——发现频繁FullGC,应用假死

    jmap -dump:format=b,file=91782.bin 91782——MAT

    如果是正常的JVM示例,Histogram试图最占内存的是byte[]和char[]两个数组,两者合计一般会占去80%左右的内存,远远超过其他对象占用的内存。

    private static void buildBar(){
        List<FutureContract> futureContractList = getAllFutureContract();
        futureContractList.forEach(contract -> {
            // do something
            executor.scheduleWithFixedDelay(() -> {
                try{
                    doFutureContract(contract);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }, 2, 3, TimeUnit.SECONDS);
        });
    }

     ============================ ============================

    https://mp.weixin.qq.com/s?__biz=MzIwMzY1OTU1NQ==&mid=2247484902&idx=1&sn=96f8859450bb410702710a31207547b4&chksm=96cd45aaa1baccbca47d6e7f94c45d343e4700f970f08619892f212368c21a37b85cdacaf05e&mpshare=1&scene=1&srcid=11211UifsB4uzpR8997c8ijo&key=2558871502c06575459481704f05bca512ba4957d6fa81ce5b6e485d2f8c51d37700580aea5c270d91be776d01e698f3ee52c3eaa932f7093711cf0d03fef7c4b4b8c1cfe9ced87ba11c546b2b843cda&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=WkTrW9fz23LjFqzeh3GP9TDogP98DJkZiwfc%2BEMNGIg4KlsUSWFD%2B43qMoUBtM%2FM

    OMG!又一个频繁FullGC的案例

    这个案例比较特殊,虽然FGC频繁,但是每次FGC后,Old都能降下去。

    -XX:+HeapDumpAfterFullGC和-XX:+HeapDumpBeforeFullGC。看命名就知道,这两个参数是在FGC前后生成dump文件。需要注意的是,一定是发生FGC,而不是CMS GC或者G1这种并发GC。

    方法1-增大Young区——方法2-优化代码,循环体内确保没有大对象常驻

    List<Long> userList = getUserIdByPage(pageNo);
    List<UserAppMongo> userAppMongoList = new ArrayList<>(userList.size());
    for (Long userId:userList){
        List<AppFromMySQL> appFromMySQLList = getUserInstalledAppList(userId);

    假设每一页1000个用户,用户平均安装的APP数量为100个。那么处理每一页时总计有20w个对象一直常驻,且无法被GC掉

    ============================ ============================

    https://mp.weixin.qq.com/s?__biz=MzIwMzY1OTU1NQ==&mid=2247485100&idx=1&sn=c98df81d8ce7518f56f2543c1b426c14&chksm=96cd46e0a1bacff61860cd4238adec40c36a154180ba3ea53adaf3a7bbdaf61928df56022890&mpshare=1&scene=1&srcid=1219XAIPdx3TS93oq00419h8&key=98f2add0c56609ce5c94c118687c26c283cde8e7d72bf35c01484a25db234e9fa1861166582b6731bdbb11e49a8151c6d4a821b99a63dc3402d00a5b16a09812be62b3e3bb61ed9bd8346c73d76845dd&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=WkTrW9fz23LjFqzeh3GP9TDogP98DJkZiwfc%2BEMNGIg4KlsUSWFD%2B43qMoUBtM%2FM

     一次 Java 内存泄漏排查过程,涨姿势

    我们决定用一个单独的 executor 跑 CompetableFuture。但是,我们因此就需要等待所有的 CompetableFuture 都工作完……通过存储他们的引用,然后调用 join()。这导致一直到索引完成,所有的 future 的引用,以及它们引用到的数据,都保持着生存的状态。这阻止了垃圾收集器及时的把它们清理掉

    大量的过早提升

    如果一个对象的生命周期很短,但是它仍然晋升到了老年代,我们就把这种现象叫做过早提升(premature tenuring)(或者叫过早升级)。老年代里的对象通常都比较大,使用与新生代不同的 GC 算法,而这些过早提升的对象占据了老年代的空间,所以它们会影响 GC 的性能。因此,我们想竭力避免过早提升。

    能想到的第一件事就是简单的增加新生代的空间。默认情况下,G1 的 GC 可以自动的调整新生代的空间,允许新生代使用堆内存的 5% 至 60%。我注意到运行的应用里,新生代和老年代的比例一直在一个很宽的幅度里变化,不过我依然动手修改了两个参数:-XX:G1NewSizePercent=40 和 -XX:G1MaxNewSizePercent=90看看会发生什么。

    建议试试设置 -XX:G1MixedGCLiveThresholdPercent=100。这个设置应该会强制 G1 GC 在 mixed GC 时不去考虑它们被填充了多少,而是强制清理所有的老年代,因此也同时清理了从新生代过早提升的对象。这应该会阻止老年代被填满从而产生一次 full GC。

    一个我们可以尝试的选项是转换到 CMS(Concurrent Mark Sweep)GC,不过由于它已经被废弃了,我们还是尽量不去使用它。

    ************************************************https://www.cnblogs.com/silyvin/p/10253766.html

    ====================================================================================

    https://mp.weixin.qq.com/s?__biz=MzUzMTA2NTU2Ng==&mid=2247485836&idx=2&sn=fc470db16f01caaafe456993fb68a234&chksm=fa49763dcd3eff2b4793d925e62a492f3f4aeea133566c048200cb7cfc1efd05a0d8e12e2ac2&mpshare=1&scene=1&srcid=1215XdXRFyt9yHpUlat0Q2k6&key=2839d46a2ccd1ada2f83742edc46fa10e80ee51d5166317547ee53a9d27526a619a5c9bd1dc15057c7584f8a79f134f289163ce62047fbd7f0f14528d609d6aacc2fcf93f518f82923b35f12e98403a8&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=9rgp7yzXt5n8w9zh1MRq1i83%2BkhrOxABmxKneg1WadnOgS9TWM04YR%2BRF92XVaxK

    涨姿势 | 服务重启后,为什么发生抖动?

    top -H -p——jstack

    "C2 CompilerThread1" daemon prio=10 tid=0x00007fce48125800 nid=0x852 waiting on condition [0x0000000000000000]``java.lang.Thread.State: RUNNABLE``Locked ownable synchronizers:``- None``"C2 CompilerThread0" daemon prio=10 tid=0x00007fce48123000 nid=0x851 waiting on condition [0x0000000000000000]``java.lang.Thread.State: RUNNABLE``Locked ownable synchronizers:``- None

    C2 CompilerThread线程项目启动初期cpu使用率那么高,它在干什么呢?

    Java程序在启动的时候所有代码的执行都处于解释执行模式,只有在运行了一段时间后,根据代码方法执行的次数,或代码里循环的执行次数等达到一定的阈值才会编译成机器码,编译成机器码后执行效率会得到大幅提升,而随着执行时间进一步拉长,JVM的各种更高级的编译优化手段就会逐渐加上,例如if条件的执行状况,逃逸分析等。这里的C2 CompilerThread线程干的就是编译优化的活。

     

    解决:

    1)通过tcpcopy软件拷贝一份线上nginx的流量进行预热,完成之后再导入线上流量。

    2)可以使用-XX:CICompilerCount参数来设置编译线程数目,这个值默认是2(之前在栈里看到有两个编译线程),我们可以加到4。

    3)

    编译方式有三种:1)Client模式;2)Server模式;3)Tiered模式。我们服务默认是Server模式。

    Server模式是采用c2高级编译的,会比较耗时且要运行一段时间才会触发编译。 Server模式的优点是编译后程序效率较高;

    Client模式比较轻量也比较快触发(比Server模式触发快),编译优化后程序效率不如Server模式;

    Tiered模式是Client模式和Server模式的折中,一开始会启用Client模式,可以在启动后更快的让部分代码先进入编译优化阶段,之后会启动Server模式,达到程序效率最大优化的目的。

    Oracle JDK 7里的HotSpot VM已经开始有比较好的Tiered编译(tiered compilation)支持,可以设置参数-XX:+TieredCompilation来启动Tiered模式,java 8默认就是Tiered模式。

    可以看出Tired模式开始阶段性能与C1相当,当到达某一时刻后性能与C2相当。

  • 相关阅读:
    ASP.NET Core 问题排查:Request.EnableRewind 后第一次读取不到 Request.Body
    解决 AutoMapper ProjectTo 不起作用的问题
    解决 ASP.NET Core 自定义错误页面对 Middleware 异常无效的问题
    ASP.NET Core 从 gitlab-ci 环境变量读取配置
    终于解决 xUnit.net 测试中无法输出到控制台的问题
    ASP.NET Core 新建线程中使用依赖注入的问题
    前端回顾:2016年 JavaScript 之星
    前端工程师和设计师必读文章推荐【系列三十五】
    AsciiMorph
    Notyf
  • 原文地址:https://www.cnblogs.com/silyvin/p/10226774.html
Copyright © 2011-2022 走看看