首页
归档
留言
友链
广告合作
壁纸
更多
美女主播
Search
1
博瑞GE车机升级/降级
5,626 阅读
2
Mac打印机设置黑白打印
4,983 阅读
3
修改elementUI中el-table树形结构图标
4,906 阅读
4
Mac客户端添加腾讯企业邮箱方法
4,686 阅读
5
intelliJ Idea 2022.2.X破解
4,368 阅读
后端开发
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
登录
/
注册
Search
标签搜索
Spring Boot
Java
Vue
Spring Cloud
Mac
MyBatis
WordPress
MacOS
asp.net
Element UI
Nacos
MySQL
.Net
Spring Cloud Alibaba
Mybatis-Plus
Typecho
jQuery
Java Script
IntelliJ IDEA
微信小程序
Laughing
累计撰写
627
篇文章
累计收到
1,421
条评论
首页
栏目
后端开发
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
页面
归档
留言
友链
广告合作
壁纸
美女主播
搜索到
4
篇与
的结果
2025-04-18
JDK自带的虚拟机性能监控、故障处理工具
Java在个版本的JDK中为我们提供了各种JVM性能监控及故障处理的小程序,当然,随着JDK版本的迭代,这些小工具的数量和功能也在不知不觉的增加与增强。本文我们会介绍JDK自带的摘日常开发过程中常用的监控虚拟机运行状态和故障处理的工具。{mtitle title="jps:虚拟机进程查看工具"/}jps命令与Linux下的ps命令类似,可以列示当前正在运行的虚拟机进程,并显示虚拟机进程的主类名称以及泽泻进程本地虚拟机唯一的ID(LVMID),后续我们介绍的工具,大都需要提供虚拟机的LVMID。对于本地虚拟机而言,LVMID与操作系统的进程ID是一致的。jps命令格式jps [option] [hostid]jps工具组要选项 选项 擢用 -q 只输出LVMID,省略主类的名称 -m 输出虚拟机进程启动时传输主类main()函数的参数 -l 输出主类的全称,如果执行的是JAR包,则输出JAR包路径 -v 输出虚拟机集成启动时的JVM参数 当然我们常用的就是jps -l命令,输出所有信息。{mtitle title="jstat:虚拟机统计信息监视工具"/}jstat用于监视虚拟机各种运行状态信息,可以显示本地或者远程虚拟机进程中的类加载、内存、垃圾回收、即时编译等运行时数据。jstat命令格式jstat [option] [lvmid] [internal] [count]option是各类参数lvmid是虚拟机进程的ID,也就是我们jps查询出的IDinternal是间隔多长时间刷新一次count是一共刷新的次数 选项 作用 -class 监视类加载、卸载信息、总空间以及类装载耗时 -gc 监视Java堆状况,包括Eden区、2个Survivor区,老年带、永久带的容量,已使用空间、垃圾收集时间合计等信息 -gccapacity监视内容与-gc基本相同,单输出内容主要关注Java堆各个区域使用到的最大、最小空间-gcutil监视内容基本与-gc相同,但输出内容主要关注已使用空间占总空间的百分比-gccause与-gcutil功能一样,但是会额外输出导致上一次垃圾回收的原因-gcnew监视新生代垃圾收集情况-gcnewcapacity监视内容与-gcnew基本相同,输出主要关注使用的最大、最小空间-gcold监视老年代垃圾收集情况-gcoldcapacity监视内容与-gcold基本相同,输出主要关注使用的最大、最小空间-gcmetacapacity元空间的最大、最小空间-compiler输出即时编译器编译过的方法、耗时等信息-printcompiilation输出已经被即时编译的方法-class类加载统计jstat -class 24272Loaded:加载class的数量Bytes:所占用空间大小Unloaded:未加载数量Bytes:未加载占用空间Time:时间-gc垃圾回收统计jstat -gc 24272S0C:第一个幸存区的大小S1C:第二个幸存区的大小S0U:第一个幸存区的使用大小S1U:第二个幸存区的使用大小EC:伊甸园区的大小EU:伊甸园区的使用大小OC:老年代大小OU:老年代使用大小MC:方法区大小MU:方法区使用大小CCSC:压缩类空间大小CCSU:压缩类空间使用大小YGC:年轻代垃圾回收次数YGCT:年轻代垃圾回收消耗时间FGC:老年代垃圾回收次数FGCT:老年代垃圾回收消耗时间GCT:垃圾回收消耗总时间-gccapacity堆内存统计jstat -gccapacity 24272NGCMN:新生代最小容量NGCMX:新生代最大容量NGC:当前新生代容量S0C:第一个幸存区大小S1C:第二个幸存区的大小EC:伊甸园区的大小OGCMN:老年代最小容量OGCMX:老年代最大容量OGC:当前老年代大小OC:当前老年代大小MCMN:最小元数据容量MCMX:最大元数据容量MC:当前元数据空间大小CCSMN:最小压缩类空间大小CCSMX:最大压缩类空间大小CCSC:当前压缩类空间大小YGC:年轻代gc次数FGC:老年代GC次数-gcutil堆内存占比统计jstat -gcutil 24272S0:幸存1区当前使用比例S1:幸存2区当前使用比例E:伊甸园区使用比例O:老年代使用比例M:元数据区使用比例CCS:压缩使用比例YGC:年轻代垃圾回收次数FGC:老年代垃圾回收次数FGCT:老年代垃圾回收消耗时间GCT:垃圾回收消耗总时间-gcnew新生代垃圾回收统计jstat -gcnew 24272S0C:第一个幸存区大小S1C:第二个幸存区的大小S0U:第一个幸存区的使用大小S1U:第二个幸存区的使用大小TT:对象在新生代存活的次数MTT:对象在新生代存活的最大次数DSS:期望的幸存区大小EC:伊甸园区的大小EU:伊甸园区的使用大小YGC:年轻代垃圾回收次数YGCT:年轻代垃圾回收消耗时间-compiler编译统计jstat -compiler 24272Compiled:编译数量。Failed:失败数量Invalid:不可用数量Time:时间FailedType:失败类型FailedMethod:失败的方法{mtitle title="jinfo:Java配置信息工具"/}jinfo(Configuration Info for Java)的作用是实时查看和调整虚拟机各项参数。说是能调整,但是基本也不会有人调整吧,其实主要还是查看参数信息,特别是一些我们没有指定的隐式的默认参数。-sysprops:查看该进程的全部配置信息jinfo -sysprops 24272其实会输出很多信息,这里只截取了部分。-flags:查看曾经赋过值的参数值jinfo -flags 24272-flag: 查看具体参数的值用法如下jinfo -flag [options] [lvmid]比如查看最大堆内存jinfo -flag MaxHeapSize 24272{mtitle title="jmap:Java内存映像工具"/}jmap主要用于生成堆转储快照,类似与java启动命令的-XX:+HeapDumpOnOutOfMemoryError。除此之外,jmap还可以查询finalize执行队列、Java堆和方法区的想起信息。选项作用-dump生成Java堆转储快照,格式为-dump:[live,]format=b,file=>,其中live子参数说明是否只dump出存活的对象-finalizerinfo显示在F-Queue中等待Finalizer线程执行finalize方法的对象-heap显示Java堆详细信息-histo显示堆中对象统计信息,包括类、实例数量、合计容量-F当虚拟机进程堆-dump选项无响应时,可强制生成dump快照-dump生成堆转储快照jmap -dump:format=b,file=test.hsprof 24272然后可以对堆转储快照进行分析。{mtitle title="jstack:Java堆栈跟踪工具"/}jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间挂起等,都是导致线程长时间停顿的常见原因。线程出现停顿时通过jstack来查看各个线程的调用堆栈,就可以获知没有响应的线程到底在后台做些什么事情,或者等待着什么资源。命令格式jstack [ option ] lvmid选项作用-F当正常输出的请求不被响应时,强制输出线程堆栈-l出堆栈外,额外显示锁信息-m如果调用本地方法的话,可以显示C/C++的堆栈jstack 24272
2025年04月18日
12 阅读
0 评论
0 点赞
2025-04-16
常用的dump文件分析工具
当系统发生内存溢出时,我们一般的处理方式都是通过抓取内存堆转储快照的形式进行分析,本文我们介绍几种日常常用的dump文件分析工具。准备工作我们通过-XX:+HeapDumpOnOutOfMemoryError参数让虚拟机在出现内存溢出时Dump出当前的内存堆转储快照,然后对Dump出的文件进行分析。示例代码如下import java.util.ArrayList; import java.util.List; public class HeapDump { static class HeapDumpObject { } public static void main(String[] args) { List<HeapDumpObject> heapDumpObjectList = new ArrayList<>(); while (true) { heapDumpObjectList.add(new HeapDumpObject()); } } }我们通过命令运行程序javac HeapDump.java java -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError HeapDump此时程序会在程序运行目录下生成.hprof格式的dump文件,我们可以针对此文件进行分析,查找内存泄漏对象的引用路径,并定位到代码具体位置。工具一:JVisualVMJVisualVM是JDK自带的dump,目前在JDK中已经没有预置此工具了,我们可以通过 官网进行下载。点击左上角,可以加载我们的dump文件可以切换摘要、线程等页签,查看不同的跟踪信息。工具二:IntelliJ Idea自带的分析器依次打开【视图】-【工具窗口】- 【分析器】点击【打开快照】,选择我们上方生成的.hprof文件可以分析最大对象以及定位我们异常发生的位置。工具三:MATMAT全称Memory Analyzer,是eclipse出品的一款独立的内存分析工具,可以在 官网下载。{message type="success" content="下载时,注意选择镜像位置,默认日本节点较慢"/}打开软件后,选择[Open a Heap Dump]可以查看对象占用空间等信息,也可以定位具体代码位置工具三:JProfilerJProfiler 是一款强大的性能分析工具,能够深入分析 Java 应用程序的 CPU 使用情况、内存消耗、线程状态和数据库查询,从而帮助快速定位性能瓶颈。打开JProfiler后,点击左上角【会话】-【打开快照】,可以选择我们本地的dump文件。双击占用最大的类,然后引用选择【传入引用】在【引用】页签,选择点击【显示更多】,可以查看异常代码的位置。
2025年04月16日
17 阅读
0 评论
0 点赞
2021-12-19
Java故障诊断与性能优化-栈上分配
正常情况下,Java对象是存储到堆上的,为了优化系统性能,Java虚拟体提供了一种栈上分配的技术,栈上分配的基本思想是:对于那些线程私有的对象(不能被其他线程访问的对象),Java虚拟机将对象打散分配到栈上,而不是分配到堆上。之所以分配到栈上,是因为在函数调用结束后,可以将对象信息自行销毁,而不需要垃圾回收器介入。栈上分配技术基础是逃逸分析,逃逸分析的目的是检查对象的作用域是否有可能逃出函数体。能够逃逸的对象下面演示一个能够逃逸的对象,因为能够逃逸,所以是无法进行栈上分配的。public class Test{ public static class User{ public String name; public int age; public User(String name,int age){ this.name=name; this.age=age; } } public static User alloc(){ User user = new User("Test",30); user.name = "张三"; user.age=40; return user; } public static void main(String[] args) throws InterruptedException{ long startTime = System.currentTimeMillis(); User user = new User("Test",30); for(int i=0;i<100000000;i++){ user= alloc(); } System.out.println(user.age); long endTime = System.currentTimeMillis(); System.out.println(endTime - startTime); } }执行java -server -Xmx20m -Xms20m -XX:+PrintGC Test可以看到代码发生了大量的GC。不能逃逸的对象相同的代码,我们只是设置对象不能逃逸,进行一下改造。public class Test{ public static class User{ public String name; public int age; public User(String name,int age){ this.name=name; this.age=age; } } public static void alloc(){ User user = new User("Test",30); user.name = "张三"; user.age=40; } public static void main(String[] args) throws InterruptedException{ long startTime = System.currentTimeMillis(); for(int i=0;i<100000000;i++){ alloc(); } long endTime = System.currentTimeMillis(); System.out.println(endTime - startTime); } }执行java -server -Xmx20m -Xms20m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-UseTLAB -XX:+EliminateAllocations Test可以看到并没有任何GC程序就执行完了。参数说明第二段启用逃逸分析时,我们参数明显是比第一段多了。-server:Server模式下,才可以启用逃逸分析。-XX:+DoEscapeAnalysis: 启用逃逸分析。-XX:-UseTLAB:TLAB全称是Thread Local Allocation Buffer,也就是线程级别的内存分配,每个线程独享一块内存,主要是针对Eden里的一块小内存,这样线程在分配内存的时候,因为这块小内存是这个线程独享的,因此不会出现锁竞争的问题,默认是开启该功能的,不建议关闭此功能,主要是保证内存分配的高效性-XX:+EliminateAllocations:开启标量替换(默认开启),运行将对象打散分配到栈上,比如我们上面User对象有id、name两个字段,那么这两个字段将会被视为两个独立的局部变量进行分配。
2021年12月19日
865 阅读
0 评论
0 点赞
2021-07-31
JVM故障诊断与性能优化之常用虚拟机参数
类加载子系统负责从文件系统或网络中加载Class信息。方法区存放类加载子系统加载的Class信息及运行时常量池信息,包括字符串的字面量和数字常量Java堆在虚拟机启动时建立,是Java程序最主要的内存工作区域,几乎所有的Java对象实例都放于Java堆中。堆空间是线程共享的。直接内存直接内存是在Java堆外直接向系统申请的内存空间,通常,访问直接内存的速度会优于Java堆。因此出于性能考虑,读写频繁的场合可能会考虑使用直接内存。直接内存在Java堆外,因此它的大小不会直接首先与Xmx指定的最大堆大小。垃圾回收系统垃圾回收器可以堆方法区、Java堆和直接内存进行回收。Java栈每个一Java虚拟机线程都有一个私有的Java栈,一个线程的Java栈在线程创建的时候被创建,Java栈中保存着局部变量、方法参数,同时和Java方法的调用、返回密切相关。本地方法栈与Java栈类似,最大的不同在于Java栈用于Java方法的调用,而本地方法栈用于本地方法的调用。作为Java虚拟机的重要扩展,Java虚拟机允许Java直接调用本地的方法(通常使用C编写)PC寄存器寄存器也是每个线程私有的空间,Java虚拟机会为每一个Java线程创建PC寄存器,在任意时刻,一个Java线程总是在执行一个方法,这个正在被执行的方法称为当前方法。如果当前方法不是本地方法,PC寄存器就会只想当前正在被执行的指令,如果当前方法是本地方法,那么PC寄存器的值就是undefined执行引擎负责执行虚拟机的字节码。常见Java虚拟机参数要诊断虚拟机,我们就要学习如何对Java虚拟机进行最基本的配置和跟踪。跟踪垃圾回收可以通过-XX:+PrintGC参数启动Java虚拟机,只要遇到GC,就会打印日志。System.out.println("##########准备申请1m内存#########"); byte[] bytes = new byte[1 * 1024 * 1024]; System.gc();GC和Full GC是垃圾回收的停顿类型,而不是区分是新生代还是年老代,如果有Full说明发生了Stop-The-World。如果是调用 System.gc()触发的,那么将显示的是Full GC (System) 4878K->1576K(249344K)表示GC 前该区域已使用容量 -> GC 后该区域已使用容量 (该区域内存总容量)0.0013118 secs表示GC所用时间,单位为秒。可以通过-XX:+PrintGCDetails参数来输出更加详细的参数。PSYoungGen:代表新生代。total 75776K, used 1951K代表新生代大小及已使用大小。[0x000000076b800000, 0x0000000770c80000, 0x00000007c0000000)代表新生代的下界、当前上界和上届。eden、from、to代表新生代的三个区,当对象在 Eden ( 包括一个 Survivor 区域,这里假设是 from 区域 ) 出生后,在经过一次 Minor GC 后,如果对象还存活,并且能够被另外一块 Survivor 区域所容纳( 上面已经假设为 from 区域,这里应为 to 区域,即 to 区域有足够的内存空间来存储 Eden 和 from 区域中存活的对象 ),则使用复制算法将这些仍然还存活的对象复制到另外一块 Survivor 区域 ( 即 to 区域 ) 中,然后清理所使用过的 Eden 以及 Survivor 区域 ( 即 from 区域 ),并且将这些对象的年龄设置为1,以后对象在 Survivor 区每熬过一次 Minor GC,就将对象的年龄 + 1,当对象的年龄达到某个值时 ( 默认是 15 岁,可以通过参数-XX:MaxTenuringThreshold 来设定 ),这些对象就会成为老年代。ParOldGen代表老年代
2021年07月31日
610 阅读
0 评论
0 点赞