范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

六JVM调优工具详解及调优实战

  文章较长,请耐心阅读,希望对您有所帮助。文末有视频教程获取方式,内容更详尽,免费分享!!!
  前置启动程序
  事先启动一个web应用程序,用jps查看其进程id,接着用各种jdk自带命令优化应用
  Jmap
  此命令可以用来查看内存信息,实例个数以及占用内存大小
  jmap -histo 14660 #查看历史生成的实例  jmap -histo:live 14660 #查看当前存活的实例,执行过程中可能会触发一次full gc
  打开log.txt,文件内容如下:
  num:序号 instances:实例数量 bytes:占用空间大小 class name:类名称, [C is a char[],[S is a short[],[I is a int[],[B is a byte[],[[I is a int[][]
  堆信息
  堆内存dump  jmap -dump:format=b,file=eureka.hprof 14660
  也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来) -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ (路径)
  示例代码:  public class OOMTest {     public static List list = new ArrayList<>();     // JVM设置        // -Xms10M -Xmx10M -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:jvm.dump     public static void main(String[] args) {       List list = new ArrayList<>();       int i = 0;       int j = 0;       while (true) {          list.add(new User(i++, UUID.randomUUID().toString()));          new User(j--, UUID.randomUUID().toString());       }    } }
  可以用jvisualvm命令工具导入该dump文件分析
  Jstack
  用jstack加进程id查找死锁,见如下示例 public class DeadLockTest {     private static Object lock1 = new Object();    private static Object lock2 = new Object();     public static void main(String[] args) {       new Thread(() -> {          synchronized (lock1) {             try {                System.out.println("thread1 begin");                Thread.sleep(5000);             } catch (InterruptedException e) {             }             synchronized (lock2) {                System.out.println("thread1 end");             }          }       }).start();        new Thread(() -> {          synchronized (lock2) {             try {                System.out.println("thread2 begin");                Thread.sleep(5000);             } catch (InterruptedException e) {             }             synchronized (lock1) {                System.out.println("thread2 end");             }          }       }).start();        System.out.println("main thread end");    } }
  "Thread-1" 线程名
  prio=5 优先级=5
  tid=0x000000001fa9e000 线程id
  nid=0x2d64 线程对应的本地线程标识nid
  java.lang.Thread.State: BLOCKED 线程状态
  还可以用jvisualvm自动检测死锁
  远程连接jvisualvm
  启动普通的jar程序JMX端口配置: java -Dcom.sun.management.jmxremote.port=8888 -Djava.rmi.server.hostname=192.168.65.60 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar microservice-eureka-server.jar
  PS:
  -Dcom.sun.management.jmxremote.port 为远程机器的JMX端口
  -Djava.rmi.server.hostname 为远程机器IP
  tomcat的JMX配置:在catalina.sh文件里的最后一个JAVA_OPTS的赋值语句下一行增加如下配置行 JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.port=8888 -Djava.rmi.server.hostname=192.168.50.60 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
  连接时确认下端口是否通畅,可以临时关闭下防火墙  systemctl stop firewalld #临时关闭防火墙
  jstack找出占用cpu最高的线程堆栈信息  /**  * 运行此代码,cpu会飙高  */ public class Math {      public static final int initData = 666;     public static User user = new User();      public int compute() {  //一个方法对应一块栈帧内存区域         int a = 1;         int b = 2;         int c = (a + b) * 10;         return c;     }      public static void main(String[] args) {         Math math = new Math();         while (true){             math.compute();         }     } }
  1,使用命令top -p ,显示你的java进程的内存情况,pid是你的java进程号,比如19663
  2,按H,获取每个线程的内存情况
  3,找到内存和cpu占用最高的线程tid,比如19664
  4,转为十六进制得到 0x4cd0,此为线程id的十六进制表示
  5,执行 jstack 19663|grep -A 10 4cd0,得到线程堆栈信息中 4cd0 这个线程所在行的后面10行,从堆栈中可以发现导致cpu飙高的调用方法
  6,查看对应的堆栈信息找出可能存在问题的代码
  Jinfo
  查看正在运行的Java应用程序的扩展参数
  查看jvm的参数
  查看java系统参数
  Jstat
  jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:
  jstat [-命令选项] [vmid] [间隔时间(毫秒)] [查询次数]
  注意:使用的jdk版本是jdk8
  垃圾回收统计
  jstat -gc pid 最常用 ,可以评估程序内存使用及GC压力整体情况
  S0C:第一个幸存区的大小,单位KB S1C:第二个幸存区的大小 S0U:第一个幸存区的使用大小 S1U:第二个幸存区的使用大小 EC:伊甸园区的大小 EU:伊甸园区的使用大小 OC:老年代大小 OU:老年代使用大小 MC:方法区大小(元空间) MU:方法区使用大小 CCSC:压缩类空间大小 CCSU:压缩类空间使用大小 YGC:年轻代垃圾回收次数 YGCT:年轻代垃圾回收消耗时间,单位s FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间,单位s GCT:垃圾回收消耗总时间,单位s
  堆内存统计
  MCMX:最大元数据容量 MC:当前元数据空间大小 CCSMN:最小压缩类空间大小 CCSMX:最大压缩类空间大小 CCSC:当前压缩类空间大小 YGC:年轻代gc次数 FGC:老年代GC次数
  新生代垃圾回收统计
  S0C:第一个幸存区的大小 S1C:第二个幸存区的大小 S0U:第一个幸存区的使用大小 S1U:第二个幸存区的使用大小 TT:对象在新生代存活的次数 MTT:对象在新生代存活的最大次数 DSS:期望的幸存区大小 EC:伊甸园区的大小 EU:伊甸园区的使用大小 YGC:年轻代垃圾回收次数 YGCT:年轻代垃圾回收消耗时间
  新生代内存统计
  NGCMN:新生代最小容量 NGCMX:新生代最大容量 NGC:当前新生代容量 S0CMX:最大幸存1区大小 S0C:当前幸存1区大小 S1CMX:最大幸存2区大小 S1C:当前幸存2区大小 ECMX:最大伊甸园区大小 EC:当前伊甸园区大小 YGC:年轻代垃圾回收次数 FGC:老年代回收次数
  老年代垃圾回收统计
  MC:方法区大小 MU:方法区使用大小 CCSC:压缩类空间大小 CCSU:压缩类空间使用大小 OC:老年代大小 OU:老年代使用大小 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间
  老年代内存统计
  OGCMN:老年代最小容量 OGCMX:老年代最大容量 OGC:当前老年代大小 OC:老年代大小 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间
  元数据空间统计
  MCMN:最小元数据容量 MCMX:最大元数据容量 MC:当前元数据空间大小 CCSMN:最小压缩类空间大小 CCSMX:最大压缩类空间大小 CCSC:当前压缩类空间大小 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间
  S0:幸存1区当前使用比例 S1:幸存2区当前使用比例 E:伊甸园区使用比例 O:老年代使用比例 M:元数据区使用比例 CCS:压缩使用比例 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间
  JVM运行情况预估
  用 jstat gc -pid 命令可以计算出如下一些关键数据,有了这些数据就可以采用之前介绍过的优化思路,先给自己的系统设置一些初始性的JVM参数,比如堆内存大小,年轻代大小,Eden和Survivor的比例,老年代的大小,大对象的阈值,大龄对象进入老年代的阈值等。
  年轻代对象增长的速率
  可以执行命令 jstat -gc pid 1000 10 (每隔1秒执行1次命令,共执行10次),通过观察EU(eden区的使用)来估算每秒eden大概新增多少对象,如果系统负载不高,可以把频率1秒换成1分钟,甚至10分钟来观察整体情况。注意,一般系统可能有高峰期和日常期,所以需要在不同的时间分别估算不同情况下对象增长速率。
  Young GC的触发频率和每次耗时
  知道年轻代对象增长速率我们就能推根据eden区的大小推算出Young GC大概多久触发一次,Young GC的平均耗时可以通过 YGCT/YGC 公式算出,根据结果我们大概就能知道 系统大概多久会因为Young GC的执行而卡顿多久。
  每次Young GC后有多少对象存活和进入老年代
  这个因为之前已经大概知道Young GC的频率,假设是每5分钟一次,那么可以执行命令 jstat -gc pid 300000 10 ,观察每次结果eden,survivor和老年代使用的变化情况,在每次gc后eden区使用一般会大幅减少,survivor和老年代都有可能增长,这些增长的对象就是每次Young GC后存活的对象,同时还可以看出每次Young GC后进去老年代大概多少对象,从而可以推算出老年代对象增长速率。
  Full GC的触发频率和每次耗时
  知道了老年代对象的增长速率就可以推算出Full GC的触发频率了,Full GC的每次耗时可以用公式 FGCT/FGC 计算得出。
  优化思路其实简单来说就是尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里。尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。
  系统频繁Full GC导致系统卡顿是怎么回事机器配置:2核4G JVM内存大小:2G 系统运行时间:7天 期间发生的Full GC次数和耗时:500多次,200多秒 期间发生的Young GC次数和耗时:1万多次,500多秒
  大致算下来每天会发生70多次Full GC,平均每小时3次,每次Full GC在400毫秒左右;
  每天会发生1000多次Young GC,每分钟会发生1次,每次Young GC在50毫秒左右。
  JVM参数设置如下: -Xms1536M -Xmx1536M -Xmn512M -Xss256K -XX:SurvivorRatio=6  -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M  -XX:+UseParNewGC  -XX:+UseConcMarkSweepGC  -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly
  大家可以结合对象挪动到老年代那些规则 推理下我们这个程序可能存在的一些问题
  经过分析感觉可能会由于对象动态年龄判断机制导致full gc较为频繁
  为了给大家看效果,我模拟了一个示例程序(见课程对应工程代码:jvm-full-gc),打印了jstat的结果如下: jstat -gc 13456 2000 10000
  对于对象动态年龄判断机制导致的full gc较为频繁可以先试着优化下JVM参数,把年轻代适当调大点: -Xms1536M -Xmx1536M -Xmn1024M -Xss256K -XX:SurvivorRatio=6  -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M  -XX:+UseParNewGC  -XX:+UseConcMarkSweepGC  -XX:CMSInitiatingOccupancyFraction=92 -XX:+UseCMSInitiatingOccupancyOnly
  优化完发现没什么变化,full gc的次数比minor gc的次数还多了
  我们可以推测下full gc比minor gc还多的原因有哪些?
  1、元空间不够导致的多余full gc
  2、显示调用System.gc()造成多余的full gc,这种一般线上尽量通过-XX:+DisableExplicitGC参数禁用,如果加上了这个JVM启动参数,那么代码中调用System.gc()没有任何效果
  3、老年代空间分配担保机制
  最快速度分析完这些我们推测的原因以及优化后,我们发现young gc和full gc依然很频繁了,而且看到有大量的对象频繁的被挪动到老年代,这种情况我们可以借助jmap命令大概看下是什么对象
  查到了有大量User对象产生,这个可能是问题所在,但不确定,还必须找到对应的代码确认,如何去找对应的代码了?
  1、代码里全文搜索生成User对象的地方(适合只有少数几处地方的情况)
  2、如果生成User对象的地方太多,无法定位具体代码,我们可以同时分析下占用cpu较高的线程,一般有大量对象不断产生,对应的方法代码肯定会被频繁调用,占用的cpu必然较高
  可以用上面讲过的jstack或jvisualvm来定位cpu使用较高的代码,最终定位到的代码如下: import java.util.ArrayList;  @RestController public class IndexController {      @RequestMapping("/user/process")     public String processUserData() throws InterruptedException {         ArrayList users = queryUsers();          for (User user: users) {             //TODO 业务处理             System.out.println("user:" + user.toString());         }         return "end";     }      /**      * 模拟批量查询用户场景      * @return      */     private ArrayList queryUsers() {         ArrayList users = new ArrayList<>();         for (int i = 0; i < 5000; i++) {             users.add(new User(i,"zhuge"));         }         return users;     } }
  同时,java的代码也是需要优化的,一次查询出500M的对象出来,明显不合适,要根据之前说的各种原则尽量优化到合适的值,尽量消除这种朝生夕死的对象导致的full gc
  内存泄露到底是怎么回事
  再给大家讲一种情况,一般电商架构可能会使用多级缓存架构,就是redis加上JVM级缓存,大多数同学可能为了图方便对于JVM级缓存就简单使用一个hashmap,于是不断往里面放缓存数据,但是很少考虑这个map的容量问题,结果这个缓存map越来越大,一直占用着老年代的很多空间,时间长了就会导致full gc非常频繁,这就是一种内存泄漏,对于一些老旧数据没有及时清理导致一直占用着宝贵的内存资源,时间长了除了导致full gc,还有可能导致OOM。
  这种情况完全可以考虑采用一些成熟的JVM级缓存框架来解决,比如ehcache等自带一些LRU数据淘汰算法的框架来作为JVM级的缓存。
  感谢您的耐心阅读,私信获取视频教程,内容更详尽,免费分享!!!
为什么喝完酒容易宿醉?上头,口渴,实际是宿醉现象(veisalgia),即酒后出现头痛疲倦晕眩恶心极度口渴,胃部不适等症状。多数爱喝酒的小伙伴,甚至长辈们喝起酒来是把好手,却也不明白什么是宿醉。为什么喝出汗不一定对身体好!这3种出汗属于异常,莫大意大多数人都觉得出汗是好的表现,说明在不断的循环和代谢,甚至觉得出汗是在排毒,多出汗积累的有害物质才能排泄出来,从而保持内部健康。实际上,出汗不一定对身体好,关键是出汗方式要正确。如不起眼的它是降尿酸高手!低升糖高纤维,好处数不清这物全身都是宝!尤其这个地方,是最强降尿酸高手,懂行的人不喝药喝它夏天是一年中蔬菜水果最丰富的时候,尤其是水果最多的季节,像西瓜桃子各种瓜类等琳琅满目。可很多人会忽略一样东西,那就1979年,中国孤胆英雄连杀56名越军,一人包围了对面整支敌军大概应该有56个吧,一大早,一名中国阵地中的小战士,睁着通红的眼睛告诉连队领导,被他亲手击毙的敌军足足有56人。要知道,对面的整支敌军,也不过百十号人而已。只有150枚子弹的小战士19项接续政策形成稳经济组合效应中央纪委国家监委网站文子玉9月5日,国务院新闻办公室举行新闻发布会介绍稳经济一揽子政策的接续政策措施有关情况。据介绍,近日国务院召开常务会议,在落实好稳经济一揽子政策的同时,再实施英雄联盟被人遗忘的活动,重新出发英雄联盟经常会有许多活动,比如决斗场和最近的战斗之夜活动,但是这些活动都只会持续一段时间,而不是一直存在。在英雄联盟里只有一个活动就是被人忘记一般,虽然一直存在,你也一直能够领到奖穆里尼奥战术单一,罗马4球惨败暴露出阵容厚度问题罗马4球完败弗留利球场,让人有点惊奇。大体看了会录像,这场罗马首发卡尔斯多普和斯皮纳佐拉两个边,各种失误,两个边打不起来这场基本就交代了。中场换穆里尼奥用贝洛蒂把后腰克里斯坦特换了辣目洋子恢复本名,baby也受牵连,知名编剧大胆曝光背后隐情辣目洋子于9月1号,在微博上发文,宣布自己恢复本名李嘉琦。给出的理由是我妈说,一切还是本来的好,听妈妈的话!还说如果觉得名字不好记,就叫我小名小辣。小编以为是心血来潮,或者真是听妈今晚开播!3部新剧同时上线,聚焦热门题材,该追哪一部?虽然过了暑期档,但剧集市场上似乎更加热闹,各大题材的剧集争相定档开播,完成第三季度KPI。而鹅厂更是豪横,两部热剧同一天开播。第一部爆笑喜剧奇葩住客该剧由崔犇犇执导,讲述了七位职业杨幂女儿小糯米将到北京上学?爷爷刘丹给出回应网易娱乐9月4日报道据媒体报道,对于近日网传杨幂女儿小糯米将来北京上学的传闻,爷爷刘丹回应媒体表示他只会提供小小的意见,决定权在刘恺威和杨幂身上。还说外界不必伤脑筋,刘恺威杨幂定会魔派虎贲精英手柄性价比完胜任天堂SwitchPro,手柄中的战斗机相信大部分资深游戏玩家,都会一致认可主机游戏才是游戏中的艺术品,像荒野大镖客2赛博朋克2077战神4等,凭借优秀的游戏性有深度的内容流畅的游玩体验,得到广大的玩家的一致好评!当然,
22家企业参与,南华大学举行核类毕业生春季供需见面会3月18日,南华大学2023届核类毕业生春季供需见面会在红湘校区南校就业大厅举行,来自全国各地的22家用人单位来校招贤纳士。该校核科学技术学院2023届全体本科生硕士毕业生近500抗皱眼霜推荐增强眼部肌肤的抗自由基氧化能力,很适合熟龄肌!抗皱眼霜推荐增强眼部肌肤的抗自由基氧化能力,很适合熟龄肌!雅诗兰黛白金眼霜如果想要一款轻薄挂的眼霜,选它是非常合适的。白金眼霜和同系列的面霜感觉很像,功效性强肤感又轻盈,对于适用肤每日元速递丨韩女团与roblox合作打造虚拟空间刘三姐数字人亮相01韩国女团TWICE与Roblox合作打造虚拟空间多人在线创作游戏平台Roblox宣布与韩国女团TWICE合作,在该平台内推出沉浸式虚拟空间TWICESquare。TWICESq又解闷又能学知识的小游戏你知道吗分享一隐匿按钮2隐匿按钮2是一款令人惊叹的益智游戏软件,TapTap评分9。6软件目前支持安卓版本。具有创新性,其主要特点是每一关都不会告诉你谜题是什么,只有一张图片,需要不断尝试老年人养生,坚持做好这5件事有利于身体健康,不妨试试大家都知道,随着年龄的增长,人体的器官功能都会逐渐退化,例如内脏,骨骼,肌肉,神经等。由此一来,无论记忆力,运动能力,消化能力都会随之下降。特别是过了60岁以后,新陈代谢的速度越来晨食壮火,午泄残精,命短阳衰古人的告诫,别不当回事!智者,追求事业不忘健康,追求利益不忘底线。愚者,只顾着低头狂赶路,不考虑结果值不值。人生在世,健康是1,健康不能代表一切,但是没有健康,其它就是一串没有任何作用的0。古人常说养身不生病时需要吃的十种食物外面的寒冷天气导致感冒和流感季节,无论您如何避免,有时您都会生病。您可以做很多事情来帮助加快恢复速度,其中之一就是确保您吃的食物会帮助您变得更好。以下是生病时最适合吃的十种食物燕麦春天饮食有讲究,三个基本原则不同季节饮食要有所区别,春天该如何做到健康饮食呢?1)食物要多样春天新陈代谢旺盛,户外活动增多,那么所需的营养也要跟着增加,故一定要注意食物品种的多样化,以防营养素缺乏。春天,温暖稍安勿躁!U20主教练安东尼奥去向牵动人心,球迷接替成耀东最应该上调的是安东尼奥,为啥?安东尼奥是救世主?据报道由于U20球员在亚洲杯上表现出色,七名球员艾菲尔丁木塔力甫刘浩帆胡荷韬李昊阳敏杰和拜合拉木上调国奥队。球迷表现最最出色的是安东体坛国足亚运队今天完成抵达新西兰后第二练,全队展现出色状态直播吧3月19日讯根据体坛网的消息,新西兰当地时间3月19日下午,中国男足亚运队完成了抵达后的第二练。全体队员在训练中展现出了相当出色的状态,尤其是门前的感觉。三天之后,亚运队将会曾雪麟杯莱斯科顿公益足球友谊赛圆满落幕3月18日下午,弘扬爱国主义精神曾雪麟杯莱斯科顿公益足球友谊赛,在深圳市松岗体育中心足球场进行。原中国足球协会副主席原广东省体育局局长董良田曾雪麟球友会秘书长薛剑雄梅县强民体育会会