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

Java开发大厂面试第26讲:生产环境如何排查问题和优化 JVM?

通过前面几个课时的学习,相信你对 JVM 的理论及实践等相关知识有了一个大体的印象。而本课时将重点讲解 JVM 的排查与优化,这样就会对 JVM 的知识点有一个完整的认识,从而可以更好地应用于实际工作或者面试了。

我们本课时的面试题是,生产环境如何排查问题?

在生产环境中排查问题和优化JVM通常涉及多个步骤,以下是一些建议的做法:

1. 监控和日志收集

  • 使用监控工具:使用如JConsole、VisualVM、JMX等监控工具来观察JVM的内存使用、GC行为、线程状态等。
  • 收集日志:启用并收集JVM的日志,特别是GC日志和异常堆栈跟踪。这些日志对于定位问题至关重要。

2. 问题排查

  • 分析GC日志:GC日志可以提供关于内存分配、垃圾回收行为以及潜在问题的详细信息。使用工具如GCViewer或GC Easy来分析日志。
  • 检查堆内存使用情况:使用jmap命令查看堆内存的使用情况,找出是否存在内存泄漏或大量对象占用内存。
  • 检查线程状态:使用jstack命令或监控工具检查线程状态,查找是否存在死锁、线程阻塞或过多的线程创建。
  • 性能分析工具:使用如YourKit、JProfiler等性能分析工具来查找性能瓶颈和优化点。

3. JVM调优

  • 堆内存调优:根据应用的需求和监控数据,调整初始堆大小(-Xms)和最大堆大小(-Xmx)。避免堆内存过小导致频繁GC,也避免堆内存过大导致资源浪费。
  • 垃圾回收器选择和调优:根据应用的特性和监控数据,选择合适的垃圾回收器(如Parallel GC、CMS GC、G1 GC)并进行调优。调整相关参数如新生代大小、老年代大小、GC触发条件等。
  • 线程堆栈大小调优:根据应用的线程使用情况,调整线程堆栈大小(-Xss)。过小的堆栈可能导致栈溢出错误,过大的堆栈则浪费内存。

4. 代码优化

  • 减少对象创建:避免在循环中创建大量短生命周期的对象,使用对象池等技术来复用对象。
  • 优化数据结构:选择合适的数据结构来存储数据,减少内存占用和提高访问效率。
  • 减少锁竞争:避免过多的锁竞争和死锁,使用无锁编程技术或优化锁的使用方式。

典型回答

如果是在生产环境中直接排查 JVM 的话,最简单的做法就是使用 JDK 自带的 6 个非常实用的命令行工具来排查。它们分别是:jps、jstat、jinfo、jmap、jhat 和 jstack,它们都位于 JDK 的 bin 目录下,可以使用命令行工具直接运行,其目录如下图所示:

Drawing 0.png

接下来我们来看看这些工具的具体使用。

1. jps(虚拟机进程状况工具)

jps(JVM Process Status tool,虚拟机进程状况工具)它的功能和 Linux 中的 ps 命令比较类似,用于列出正在运行的 JVM 的 LVMID(Local Virtual Machine IDentifier,本地虚拟机唯一 ID),以及 JVM 的执行主类、JVM 启动参数等信息。语法如下:

jps [options] [hostid]

常用的 options 选项:

  • -l:用于输出运行主类的全名,如果是 jar 包,则输出 jar 包的路径;

  • -q:用于输出 LVMID(Local Virtual Machine Identifier,虚拟机唯一 ID);

  • -m:用于输出虚拟机启动时传递给主类 main() 方法的参数;

  • -v:用于输出启动时的 JVM 参数。

使用实例:

➜  jps -l
68848
40085 org.jetbrains.jps.cmdline.Launcher
40086 com.example.optimize.NativeOptimize
40109 jdk.jcmd/sun.tools.jps.Jps
68879 org.jetbrains.idea.maven.server.RemoteMavenServer36
➜  jps -q
40368
68848
40085
40086
68879
➜  jps -m
40400 Jps -m
68848
40085 Launcher /Applications/IntelliJ IDEA2.app/Contents/lib/idea_rt.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/oro-2.0.8.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/resources_en.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/maven-model-3.6.1.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/qdox-2.0-M10.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/plexus-component-annotations-1.7.1.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/httpcore-4.4.13.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/maven-resolver-api-1.3.3.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/netty-common-4.1.47.Final.jar:/Applications/IntelliJ IDEA2.app/Contents/plugins/java/lib/maven-resolver-connector-basic-1.3.3.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/maven-artifact-3.6.1.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/plexus-utils-3.2.0.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/netty-resolver-4.1.47.Final.jar:/Applications/IntelliJ IDEA2.app/Contents/lib/guava-28.2-
40086 NativeOptimize
68879 RemoteMavenServer36
➜  jps -v
68848  -Xms128m -Xmx2048m -XX:ReservedCodeCacheSize=240m -XX:+UseCompressedOops -Dfile.encoding=UTF-8 -XX:+UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=50 -ea -XX:CICompilerCount=2 -Dsun.io.useCanonPrefixCache=false -Djava.net.preferIPv4Stack=true -Djdk.http.auth.tunneling.disabledSchemes="" -XX:+HeapDumpOnOutOfMemoryError -XX:-OmitStackTraceInFastThrow -Djdk.attach.allowAttachSelf -Dkotlinx.coroutines.debug=off -Djdk.module.illegalAccess.silent=true -Xverify:none -XX:ErrorFile=/Users/admin/java_error_in_idea_%p.log -XX:HeapDumpPath=/Users/admin/java_error_in_idea.hprof -javaagent:/Users/admin/.jetbrains/jetbrains-agent-v3.2.0.de72.619 -Djb.vmOptionsFile=/Users/admin/Library/Application Support/JetBrains/IntelliJIdea2020.1/idea.vmoptions -Didea.paths.selector=IntelliJIdea2020.1 -Didea.executable=idea -Didea.home.path=/Applications/IntelliJ IDEA2.app/Contents -Didea.vendor.name=JetBrains
40085 Launcher -Xmx700m -Djava.awt.headless=true -Djava.endorsed.dirs="" -Djdt.compiler.useSingleThread=true -Dpreload.project.path=/Users/admin/github/blog-example/blog-example -Dpreload.config.path=/Users/admin/Library/Application Support/JetBrains/IntelliJIdea2020.1/options -Dcompile.parallel=false -Drebuild.on.dependency.change=true -Djava.net.preferIPv4Stack=true -Dio.netty.initialSeedUniquifier=1366842080359982660 -Dfile.encoding=UTF-8 -Duser.language=zh -Duser.country=CN -Didea.paths.selector=IntelliJIdea2020.1 -Didea.home.path=/Applications/IntelliJ IDEA2.app/Contents -Didea.config.path=/Users/admin/Library/Application Support/JetBrains/IntelliJIdea2020.1 -Didea.plugins.path=/Users/admin/Library/Application Support/JetBrains/IntelliJIdea2020.1/plugins -Djps.log.dir=/Users/admin/Library/Logs/JetBrains/IntelliJIdea2020.1/build-log -Djps.fallback.jdk.home=/Applications/IntelliJ IDEA2.app/Contents/jbr/Contents/Home -Djps.fallback.jdk.version=11.0.6 -Dio.netty.noUnsafe=true -Djava.io.tmpdir=/Users/admin/Library/Caches/Je
40086 NativeOptimize -Dfile.encoding=UTF-8
40425 Jps -Dapplication.home=/Users/admin/Library/Java/JavaVirtualMachines/openjdk-14/Contents/Home -Xms8m -Djdk.module.main=jdk.jcmd
68879 RemoteMavenServer36 -Djava.awt.headless=true -Dmaven.defaultProjectBuilder.disableGlobalModelCache=true -Xmx768m -Didea.maven.embedder.version=3.6.1 -Dmaven.ext.class.path=/Applications/IntelliJ IDEA2.app/Contents/plugins/maven/lib/maven-event-listener.jar -Dfile.encoding=UTF-8
2. jstat(虚拟机统计信息监视工具)

jstat(JVM Statistics Monitoring Tool,虚拟机统计信息监视工具)用于监控虚拟机的运行状态信息。

例如,我们用它来查询某个 Java 进程的垃圾收集情况,示例如下:

➜  jstat -gc 43704S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT    CGC    CGCT     GCT
10752.0 10752.0  0.0    0.0   65536.0   5243.4   175104.0     0.0     4480.0 774.0  384.0   75.8       0    0.000   0      0.000   -          -    0.000

参数说明如下表所示:

参数说明
S0C年轻代中第一个存活区的大小
S1C年轻代中第二个存活区的大小
S0U年轻代中第一个存活区已使用的空间(字节)
S1U年轻代中第二个存活区已使用的空间(字节)
ECEden 区大小
EU年轻代中 Eden 区已使用的空间(字节)
OC老年代大小
OU老年代已使用的空间(字节)
YGC从应用程序启动到采样时 young gc 的次数
YGCT从应用程序启动到采样时 young gc 的所用的时间(s)
FGC从应用程序启动到采样时 full gc 的次数
FGCT从应用程序启动到采样时 full gc 的所用的时间
GCT从应用程序启动到采样时整个 gc 所用的时间

注意:年轻代的 Eden 区满了会触发 young gc,老年代满了会触发 old gc。full gc 指的是清除整个堆,包括 young 区 和 old 区。

jstat 常用的查询参数有:

  • -class,查询类加载器信息;

  • -compiler,JIT 相关信息;

  • -gc,GC 堆状态;

  • -gcnew,新生代统计信息;

  • -gcutil,GC 堆统计汇总信息。

3. jinfo(查询虚拟机参数配置工具)

jinfo(Configuration Info for Java)用于查看和调整虚拟机各项参数。语法如下:

jinfo <option> <pid>

查看 JVM 参数示例如下:

➜  jinfo -flags 45129
VM Flags:
-XX:CICompilerCount=3 -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=1431306240 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=89128960 -XX:OldSize=179306496 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC

其中 45129 是使用 jps 查询的 LVMID。
我们可以通过 jinfo -flag [+/-]name 来修改虚拟机的参数值,比如下面的示例:

➜  jinfo -flag PrintGC 45129 # 查询是否开启 GC 打印
-XX:-PrintGC
➜  jinfo -flag +PrintGC 45129 # 开启 GC 打印
➜  jinfo -flag PrintGC 45129 # 查询是否开启 GC 打印
-XX:+PrintGC
➜  jinfo -flag -PrintGC 45129 # 关闭 GC 打印
➜  jinfo -flag PrintGC 45129 # 查询是否开启 GC 打印
-XX:-PrintGC
4. jmap(堆快照生成工具)

jmap(Memory Map for Java)用于查询堆的快照信息。

查询堆信息示例如下:

➜  jmap -heap 45129
Attaching to process ID 45129, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.101-b13
using thread-local object allocation.
Parallel GC with 6 thread(s)
Heap Configuration:MinHeapFreeRatio         = 0MaxHeapFreeRatio         = 100MaxHeapSize              = 4294967296 (4096.0MB)NewSize                  = 89128960 (85.0MB)MaxNewSize               = 1431306240 (1365.0MB)OldSize                  = 179306496 (171.0MB)NewRatio                 = 2SurvivorRatio            = 8MetaspaceSize            = 21807104 (20.796875MB)CompressedClassSpaceSize = 1073741824 (1024.0MB)MaxMetaspaceSize         = 17592186044415 MBG1HeapRegionSize         = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:capacity = 67108864 (64.0MB)used     = 5369232 (5.1204986572265625MB)free     = 61739632 (58.87950134277344MB)8.000779151916504% used
From Space:capacity = 11010048 (10.5MB)used     = 0 (0.0MB)free     = 11010048 (10.5MB)0.0% used
To Space:capacity = 11010048 (10.5MB)used     = 0 (0.0MB)free     = 11010048 (10.5MB)0.0% used
PS Old Generationcapacity = 179306496 (171.0MB)used     = 0 (0.0MB)free     = 179306496 (171.0MB)0.0% used

2158 interned Strings occupying 152472 bytes.

我们也可以直接生成堆快照文件,示例如下:

➜  jmap -dump:format=b,file=/Users/admin/Documents/2020.dump 47380
Dumping heap to /Users/admin/Documents/2020.dump ...
Heap dump file created
5. jhat(堆快照分析功能)

jhat(JVM Heap Analysis Tool,堆快照分析工具)和 jmap 搭配使用,用于启动一个 web 站点来分析 jmap 生成的快照文件。

执行示例如下:

jhat /Users/admin/Documents/2020.dump
Reading from /Users/admin/Documents/2020.dump...
Dump file created Tue May 26 16:12:41 CST 2020
Snapshot read, resolving...
Resolving 17797 objects...
Chasing references, expect 3 dots...
Eliminating duplicate references...
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

上述信息表示 jhat 启动了一个 http 的服务器端口为 7000 的站点来展示信息,此时我们在浏览器中输入:http://localhost:7000/,会看到如下图所示的信息:

Drawing 1.png

6. jstack(查询虚拟机当前的线程快照信息)

jstack(Stack Trace for Java)用于查看当前虚拟机的线程快照,用它可以排查线程的执行状况,例如排查死锁、死循环等问题。

比如,我们先写一段死锁的代码:

public class NativeOptimize {private static Object obj1 = new Object();private static Object obj2 = new Object();public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {synchronized (obj2) {System.out.println(Thread.currentThread().getName() + "锁住 obj2");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (obj1) {// 执行不到这里System.out.println("1秒钟后," + Thread.currentThread().getName()+ "锁住 obj1");}}}}).start();synchronized (obj1) {System.out.println(Thread.currentThread().getName() + "锁住 obj1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (obj2) {// 执行不到这里System.out.println("1秒钟后," + Thread.currentThread().getName()+ "锁住 obj2");}}}
}

以上程序的执行结果如下:

main:锁住 obj1
Thread-0:锁住 obj2

此时我们使用 jstack 工具打印一下当前线程的快照信息,结果如下:

➜  bin jstack -l 50016
2020-05-26 18:01:41
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode):
"Attach Listener" #10 daemon prio=9 os_prio=31 tid=0x00007f8c00840800 nid=0x3c03 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None
"Thread-0" #9 prio=5 os_prio=31 tid=0x00007f8c00840000 nid=0x3e03 waiting for monitor entry [0x00007000100c8000]java.lang.Thread.State: BLOCKED (on object monitor)at com.example.optimize.NativeOptimize$1.run(NativeOptimize.java:25)- waiting to lock <0x000000076abb62d0> (a java.lang.Object)- locked <0x000000076abb62e0> (a java.lang.Object)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- None
"Service Thread" #8 daemon prio=9 os_prio=31 tid=0x00007f8c01814800 nid=0x4103 runnable [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None
"C1 CompilerThread2" #7 daemon prio=9 os_prio=31 tid=0x00007f8c0283c800 nid=0x4303 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None
"C2 CompilerThread1" #6 daemon prio=9 os_prio=31 tid=0x00007f8c0300a800 nid=0x4403 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None
"C2 CompilerThread0" #5 daemon prio=9 os_prio=31 tid=0x00007f8c0283c000 nid=0x3603 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007f8c0283b000 nid=0x4603 runnable [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None
"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007f8c03001000 nid=0x5003 in Object.wait() [0x000070000f8ad000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x000000076ab08ee0> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)- locked <0x000000076ab08ee0> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)Locked ownable synchronizers:- None
"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007f8c03000000 nid=0x2f03 in Object.wait() [0x000070000f7aa000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x000000076ab06b50> (a java.lang.ref.Reference$Lock)at java.lang.Object.wait(Object.java:502)at java.lang.ref.Reference.tryHandlePending(Reference.java:191)- locked <0x000000076ab06b50> (a java.lang.ref.Reference$Lock)at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)Locked ownable synchronizers:- None
"main" #1 prio=5 os_prio=31 tid=0x00007f8c00802800 nid=0x1003 waiting for monitor entry [0x000070000ef92000]java.lang.Thread.State: BLOCKED (on object monitor)at com.example.optimize.NativeOptimize.main(NativeOptimize.java:41)- waiting to lock <0x000000076abb62e0> (a java.lang.Object)- locked <0x000000076abb62d0> (a java.lang.Object)Locked ownable synchronizers:- None
"VM Thread" os_prio=31 tid=0x00007f8c01008800 nid=0x2e03 runnable
"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007f8c00803000 nid=0x2007 runnable

“GC task thread#1 (ParallelGC)” os_prio=31 tid=0x00007f8c00006800 nid=0x2403 runnable

“GC task thread#2 (ParallelGC)” os_prio=31 tid=0x00007f8c01800800 nid=0x2303 runnable
“GC task thread#3 (ParallelGC)” os_prio=31 tid=0x00007f8c01801800 nid=0x2a03 runnable
“GC task thread#4 (ParallelGC)” os_prio=31 tid=0x00007f8c01802000 nid=0x5403 runnable
“GC task thread#5 (ParallelGC)” os_prio=31 tid=0x00007f8c01006800 nid=0x2d03 runnable
“VM Periodic Task Thread” os_prio=31 tid=0x00007f8c00010800 nid=0x3803 waiting on condition
JNI global references: 6
Found one Java-level deadlock:

“Thread-0”:
  waiting to lock monitor 0x00007f8c000102a8 (object 0x000000076abb62d0, a java.lang.Object),
  which is held by “main”
“main”:
  waiting to lock monitor 0x00007f8c0000ed58 (object 0x000000076abb62e0, a java.lang.Object),
  which is held by “Thread-0”

Java stack information for the threads listed above:

“Thread-0”:
at com.example.optimize.NativeOptimize$1.run(NativeOptimize.java:25)
- waiting to lock <0x000000076abb62d0> (a java.lang.Object)
- locked <0x000000076abb62e0> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
“main”:
at com.example.optimize.NativeOptimize.main(NativeOptimize.java:41)
- waiting to lock <0x000000076abb62e0> (a java.lang.Object)
- locked <0x000000076abb62d0> (a java.lang.Object)

Found 1 deadlock.

从上述信息可以看出使用 jstack ,可以很方便地排查出代码中出现“deadlock”(死锁)的问题。

考点分析

Java 虚拟机的排查工具是一个合格程序员必备的技能,使用它我们可以很方便地定位出问题的所在,尤其在团队合作的今天,每个人各守一摊很容易出现隐藏的 bug(缺陷)。因此使用这些排查功能可以帮我们快速地定位并解决问题,所以它也是面试中常问的问题之一。

和此知识点相关的面试题还有以下这些:

  • 除了比较实用的命令行工具之外,有没有方便一点的排查工具?

  • JVM 常见的调优手段有哪些?

知识扩展

可视化排查工具

JVM 除了上面的 6 个基础命令行工具之外,还有两个重要的视图调试工具,即 JConsole 和 JVisualVM,它们相比于命令行工具使用更方便、操作更简单、结果展现也更直观。

JConsole 和 JVisualVM 都位于 JDK 的 bin 目录下,JConsole(Java Monitoring and Management Console)是最早期的视图调试工具,其启动页面如下图所示:

Drawing 2.png

可以看出我们可以用它来连接远程的服务器,或者是直接调试本机,这样就可以在不消耗生产环境的性能下,从本机启动 JConsole 来连接服务器。选择了调试的进程之后,运行界面如下图所示:

Drawing 3.png

从上图可以看出,使用 JConsole 可以监控线程、CPU、类、堆以及 VM 的相关信息,同样我们可以通过线程这一页的信息,发现之前我们故意写的死锁问题,如下图所示:

Drawing 4.png

可以看到 main(主线程)和 Thread-0 线程处于死锁状态。

JVisualVM 的启动图如下图所示:

Drawing 5.png

由上图可知,JVisualVM 既可以调试本地也可以调试远程服务器,当我们选择了相关的进程之后,运行如下图所示:

Drawing 6.png

可以看出 JVisualVM 除了包含了 JConsole 的信息之外,还有更多的详细信息,并且更加智能。例如,线程死锁检查的这页内容如下图所示:

Drawing 7.png

可以看出 JVisualVM 会直接给你一个死锁的提示,而 JConsole 则需要程序员自己分析。

JVM 调优

JVM 调优主要是根据实际的硬件配置信息重新设置 JVM 参数来进行调优的,例如,硬件的内存配置很高,但 JVM 因为是默认参数,所以最大内存和初始化堆内存很小,这样就不能更好地利用本地的硬件优势了。因此,需要调整这些参数,让 JVM 在固定的配置下发挥最大的价值。

JVM 常见调优参数包含以下这些:

  • -Xmx,设置最大堆内存大小;

  • -Xms,设置初始堆内存大小;

  • -XX:MaxNewSize,设置新生代的最大内存;

  • -XX:MaxTenuringThreshold,设置新生代对象经过一定的次数晋升到老生代;

  • -XX:PretrnureSizeThreshold,设置大对象的值,超过这个值的对象会直接进入老生代;

  • -XX:NewRatio,设置分代垃圾回收器新生代和老生代内存占比;

  • -XX:SurvivorRatio,设置新生代 Eden、Form Survivor、To Survivor 占比。

我们要根据自己的业务场景和硬件配置来设置这些值。例如,当我们的业务场景会有很多大的临时对象产生时,因为这些大对象只有很短的生命周期,因此需要把“-XX:MaxNewSize”的值设置的尽量大一些,否则就会造成大量短生命周期的大对象进入老生代,从而很快消耗掉了老生代的内存,这样就会频繁地触发 full gc,从而影响了业务的正常运行。

最后

今天我们分享了 JVM 排查的 6 个基本命令行工具:jps、jstat、jinfo、jmap、jhat、jstack,以及 2 个视图排查工具:JConsole 和 JVisualVM;同时还讲了 JVM 的常见调优参数,希望的内容可以切实的帮助到你。


相关文章:

Java开发大厂面试第26讲:生产环境如何排查问题和优化 JVM?

通过前面几个课时的学习&#xff0c;相信你对 JVM 的理论及实践等相关知识有了一个大体的印象。而本课时将重点讲解 JVM 的排查与优化&#xff0c;这样就会对 JVM 的知识点有一个完整的认识&#xff0c;从而可以更好地应用于实际工作或者面试了。 我们本课时的面试题是&#x…...

计算机科学的先驱者们

1. 艾伦图灵&#xff08;Alan Turing&#xff09;&#xff1a; 图灵是计算机科学和人工智能的先驱之一&#xff0c;他提出了“图灵机”的概念&#xff0c;这是一种理论上的计算模型&#xff0c;奠定了现代计算机理论的基础。在第二次世界大战期间&#xff0c;图灵领导了一个团…...

哈希双指针

文章目录 一、哈希1.1两数之和1.2字母异位词分组1.3最长子序列 二、双指针2.1[移动零](https://leetcode.cn/problems/move-zeroes/description/?envTypestudy-plan-v2&envIdtop-100-liked)2.2[盛最多水的容器](https://leetcode.cn/problems/container-with-most-water/d…...

【网络】UDP协议

应用层协议是请求与响应服务&#xff0c;客户端的请求与服务器的响应是通过应用层传输到网络中的&#xff0c;但再实际上&#xff0c;应用层并不能直接通信&#xff0c;需要将数据进行报头的封装&#xff0c;向下层交付&#xff0c;贯穿整个协议栈。我们已经谈到应用层协议负责…...

牛马真的沉默了,入职第一天就干活

入职第一天就干活的&#xff0c;就问还有谁&#xff0c;搬来一台N手电脑&#xff0c;第一分钟开机&#xff0c;第二分钟派活&#xff0c;第三分钟干活&#xff0c;巴适。。。。。。 打开代码发现问题不断 读取配置文件居然读取两个配置文件&#xff0c;一个读一点&#xff0c;…...

解决在cmd里下载的库,但IDLE还是显示不存在的问题

原因一&#xff1a; 环境变量配置 首先&#xff0c;你需要确认你安装库的时候使用的Python环境是否和IDLE使用的Python环境是同一个。如果cmd中你使用的是系统路径下的Python&#xff0c;而IDLE使用的是另一个路径下的Python&#xff0c;那么你在cmd中下载的库&#xff0c;IDL…...

嵌入式全栈开发学习笔记---C语言笔试复习大全23

目录 联合体 联合体的定义 联合体的长度 如果来判断设备的字节序&#xff1f; 如何把大端数据转换成小端数据&#xff1f; 枚举 枚举的定义 上一篇复习了结构体&#xff0c;这一节复习联合体和枚举。 说明&#xff1a;我们学过单片机的一般都是有C语言基础的了&#xff…...

C++函数指针,键值对集合的学习

这段代码使用了 std::unordered_map 来存储 std::wstring 作为键&#xff08;key&#xff09;&#xff0c;而对应的值&#xff08;value&#xff09;是一个 std::function<void(std::array<int, 5>, SomeClass&, int)> 类型的函数指针。这个结构使得根据字符串…...

新人攻略:避开这3大坑,让老员工主动带你飞!

进入职场的新人们&#xff0c;常常会感到困惑和挑战。他们可能会发现自己在与老员工的交流中遇到难题&#xff0c;甚至发现老员工并不愿意花费时间和精力去指导他们。这背后的原因是什么呢&#xff1f;又该如何改善这一现象呢&#xff1f;本文将从新员工的角度出发&#xff0c;…...

汽车液态电池隔膜的作用

标签: 汽车液态电池隔膜的作用; 聚乙烯(PE);聚丙烯(PP) 问题:汽车液态电池隔膜的作用? 汽车液态电池隔膜的作用 汽车液态电池中的隔膜是一个至关重要的组件,它在电池的性能、安全性和寿命方面起着关键作用。下面详细讲述隔膜的主要功能和作用: 1. 电化学隔离 隔…...

汽车液态电池充电时,充电时的化学反应是怎样的? 电池电量是怎么充满的?

标签: 汽车液态电池充电时的化学反应; 电池充电过程;锂电池,石墨负极 问题:汽车液态电池充电时,充电时的化学反应是怎样的? 电池电量是怎么充满的? 汽车液态电池充电时的化学反应 汽车液态电池(如锂离子电池)在充电时,通过电化学反应将电能转化为化学能并储存在电…...

Topk问题以及二叉树的三种层序遍历和基本操作

一、Topk问题 1、问题描述 TOP-K问题&#xff1a;即求数据结合中前K个最大的元素或者最小的元素&#xff0c;一般情况下数据量都比较大。 比如&#xff1a;专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。 2、思路 对于Top-K问题&#xff0c;能想到的最简单直接的…...

深度学习设计模式之桥接模式

文章目录 前言一、介绍二、详细分析1.核心组成2.实现步骤3.代码示例4.优缺点优点缺点 5.使用场景 总结 前言 桥接模式是将抽象部分与实现部分分离&#xff0c;使它们都可以独立的变化。 一、介绍 桥接模式是结构型设计模式&#xff0c;主要是将抽象部分与实现部分分离&#x…...

设计模式 17 组合模式 Composite Pattern

设计模式 17 组合模式 Composite Pattern 1.定义 组合模式&#xff08;Composite Pattern&#xff09;&#xff0c;又叫部分整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象&#xff0c;用来表示部分以及整体层次。这种类型的设…...

【经典论文阅读10】MNS采样——召回双塔模型的最佳拍档

这篇发表于2020 WWW 上的会议论文&#xff0c;提出一种MNS方式的负样本采样方法。众所周知&#xff0c;MF方法难以解决冷启动问题&#xff0c;于是进化出双塔模型&#xff0c;但是以双塔模型为基础的召回模型的好坏十分依赖负样本的选取。为了解决Batch内负样本带来的选择性偏差…...

串行低功耗芯片间媒体总线(SLIMbus)介绍

文章目录 SLIMbus简介slimbus设备和设备类Manager DeviceFramer DeviceInterface DeviceGeneric Device (Function)SLIMbus组件简单的SLIMbus组件复杂的SLIMbus组件SLIMbus的DATA和CLKSLIMbus的Clock Frequencies和GearsCells, Slots, Subframes, Frames, and...

esp32-S3 使用自带的大模型,实现本地文字转语言tts

目录 CMakeLists.txt文件中: 初始化以及实际运用代码: 在partitions.csv 内存分配文件中,添加voice_data项...

Redis事务(1)

什么是事务&#xff1f; Redis 的事务和 MySQL 的事务概念上是类似的. 都是把⼀系列操作绑定成⼀组. 让这⼀组能够批量执行。 但是注意体会 Redis 的事务和 MySQL 事务的区别: 弱化的原⼦性: redis 没有 “回滚机制”. 只能做到这些操作 “批量执⾏”. 不能做到 “⼀个失败就…...

202206青少年软件编程(Python)等级考试试卷(四级)

第 1 题 【单选题】 有如下 Python 程序, 包含 lambda 函数, 运行该程序后, 输出的结果是? ( ) g = lambda x,y:x*yprint(g(2,3))A :2 B :3 C :6 D :8 正确答案:C 试题解析: g = lambda x, y: x*y, lambda 函数返回参数 x 和 y 的积, 因此选 C。 第 2 题 【单选…...

大作业爬取手机数据,实现手机推荐系统以及朋友圈手机论坛

1、功能简介 &#xff08;1&#xff09;用户注册与用户登录 &#xff08;2&#xff09;手机搜索、手机比拼、手机个性化推荐 &#xff08;3&#xff09;点击搜索的手机图片会就用户行为&#xff0c;轮播展示用户行为&#xff0c;推荐点击次数靠前的手机 &#xff08;4&#xf…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...