`
deepinmind
  • 浏览: 451376 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
1dc14e59-7bdf-33ab-841a-02d087aed982
Java函数式编程
浏览量:41617
社区版块
存档分类
最新评论

通过JVM日志来进行安全点分析

阅读更多
许多事件都可能会导致JVM暂停所有的应用线程。这类暂停又被称为"stop-the-world"(STW)暂停。触发STW暂停最常见的原因就是垃圾回收了(github中的一个例子](https://github.com/gvsmirnov/java-perv/blob/master/labs-8/src/main/java/ru/gvsmirnov/perv/labs/safepoints/FullGc.java)),但不同的JIT活动([例子](https://github.com/gvsmirnov/java-perv/blob/master/labs-8/src/main/java/ru/gvsmirnov/perv/labs/safepoints/Deoptimization.java)),偏向锁擦除([例子](https://github.com/gvsmirnov/java-perv/blob/master/labs-8/src/main/java/ru/gvsmirnov/perv/labs/safepoints/BiasedLocks.java)),[特定的JVMTI操作,以及许多场景也可能会导致应用程序暂停。

应用程序线程可以被安全地停止掉的那个时间点,就叫做安全点。这一术语也通常用来指代SWT暂停。


通常来讲GC日志都是打开的。然而,并非所有安全点的信息都能完整地记录下来。想获取到完整的日志,可以使用下列的JVM选项:



[*]XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime




从参数名字来看你可能会觉得是与GC相关的,其实不然——打开这些选项能够记录下所有的安全点,而不止是GC暂停的。如果你用上述的选项来运行下这个例子(github源码

你会在标准输出中看到如下信息:


Application time: 0.3440086 seconds
Total time for which application threads were stopped: 0.0620105 seconds
Application time: 0.2100691 seconds
Total time for which application threads were stopped: 0.0890223 seconds





很通俗易懂(和GC日志相比来说)——从中你可以得知应用程序在前344毫秒中是在处理实际工作的,然后将所有线程暂停了62毫秒,紧接着又工作了210ms,然后又暂停了89ms。

你还可以将这些选项与GC的选项结合起来使用,比如将上面这个程序加上-XX:+PrintGCDetails 选项后再运行一次,输出则变成这样了;


[Full GC (Ergonomics) [PSYoungGen: 1375253K->0K(1387008K)] [ParOldGen: 2796146K->2049K(1784832K)] 4171400K->2049K(3171840K), [Metaspace: 3134K->3134K(1056768K)], 0.0571841 secs] [Times: user=0.02 sys=0.04, real=0.06 secs] 
Total time for which application threads were stopped: 0.0572646 seconds, Stopping threads took: 0.0000088 seconds



综上可知,应用线程被强制暂停了57ms来进行垃圾回收。其中又有8ms是用来等待所有的应用线程都到达安全点。如果我们用同样的选项运行另一个例子(Github源码)的话,输出又变成这样的了:


Total time for which application threads were stopped: 0.0001273 seconds, Stopping threads took: 0.0000196 seconds
Total time for which application threads were stopped: 0.0000648 seconds, Stopping threads took: 0.0000174 seconds



光从这些信息我们无从得知是什么导致的暂停,因为看不出有任何的垃圾回收的活动。如果你想更详细地了解安全点的信息的话,可以使用这组JVM参数:


[*]XX:+PrintSafepointStatistics  -XX:PrintSafepointStatisticsCount=1



启用这些参数使得JVM会将一些额外的信息记录到标准输出中,大概类似这样:


5.141: RevokeBias                       [      13          0              2    ]      [     0     0     0     0     0    ]  0  
Total time for which application threads were stopped: 0.0000782 seconds, Stopping threads took: 0.0000269 seconds



关于安全点的信息是按照如下的顺序进行显示的:

  • JVM启动之后所经历的毫秒数(上例中是5.141)
  • 触发这次暂停的操作名(RevokeBias)。
  •                 如果你看见"no vm operation",就说明这是一个"保证安全点"。JVM默认每秒会触发一次安全点来处理那些非紧急的排队的操作。GuaranteedSafepointInterval选项可以用来调整这一行为(设置为0的话就会禁用该功能)
  • 停在安全点的线程的数量(13)
  • 在安全点开始时仍在运行的线程的数量(0)
  • 虚拟机操作开始执行前仍处于阻塞状态的线程的数量(2)
  • 到达安全点时的各个阶段以及执行操作所花的时间(0)

  • 因此我们可以看出,使用了偏向锁会导致大量的STW暂停,尽管它们只花了几十毫秒。在如今这个大量使用并发的年代,禁用它们也不是什么罕见的事情。


    不管怎样,多打印些日志总会减少一些麻烦事的。你可以使用如下的JVM参数:

    
    [*]XX:+LogVMOutput -XX:LogFile=vm.log
    



    所有的虚拟机日志都会输出到vm.log文件中。如何解读这些日志并做出响应是一个很大的课题,这已经远超本文所讨论的范围了,不过未来我仍会更新一到两篇文章来讲下这个,请拭目以待.


    英文原文链接

    原文链接



    1
    0
    分享到:
    评论

    相关推荐

      JVM 输出 GC 日志导致 JVM 卡住

      作者通过分析 Safepoint 日志和 GC 日志,发现了三个不同的现象:第一,等待所有线程进入安全点的时间特别长;第二,处于 safepoint 时间过长的,并且原因是 GC;第三,处于 safepoint 时间过长的,但是间隔日志的...

      JVM-SANDBOX基于JVM的实时无侵入AOP框架容器

      AOP(Aspect-Oriented Programming)是一种编程范式,它将关注点分离,使得系统中的横切关注点(如日志、事务管理)可以独立于业务逻辑进行编写和维护。JVM-SANDBOX通过动态代理技术实现了这一目标,允许开发者在...

      jvm分析资料及工具1

      6. **JVM日志与故障排查**:通过-JDK自带的jmap、jhat、jstack和jinfo等命令,可以生成堆转储、分析内存、查看线程堆栈信息和配置信息,辅助故障诊断。 7. **类加载机制**:JVM的双亲委派模型确保了类加载的一致性...

      JVM-Sandbox,基于jvm的实时无创aop框架容器.zip

      JVM-Sandbox是一个开源项目,其核心理念是提供一个基于Java虚拟机(JVM)的实时、无侵入的面向切面编程(AOP)框架...对于那些希望在运行时进行监控、优化或安全控制的项目,JVM-Sandbox是一个非常有价值的解决方案。

      JVM面试题资源

      - **GC日志分析**:通过-XX:+PrintGC、-XX:+PrintGCDetails等参数输出GC信息,帮助优化。 - **类加载优化**:避免过多的类加载,减少内存占用。 5. **JVM性能监控和故障排查工具** - **jconsole、jvisualvm**:...

      监测JVM各项性能指标

      - **jinfo**:提供配置信息,如JVM参数,可以实时修改某些非安全的运行时参数。 - **jmap**:用于生成堆内存映射或dump文件,便于分析内存泄漏。 - **jhat**:分析堆dump文件,查找内存泄漏或对象引用问题。 2. ...

      JVM逃逸_分析、利用与防御.pdf

      JVM逃逸是一种高级的软件安全问题,涉及到Java虚拟机(JVM)的安全机制被绕过,允许恶意代码获取不应有的权限或执行非授权操作。本文主要围绕JVM逃逸展开,包括其分析、利用和防御策略。 首先,我们要理解Java的...

      jvm_jvm新手_jvm_

      以下是一些关于JVM的关键知识点: 1. **内存区域**: - **堆内存**:所有对象实例都在堆中分配内存,是JVM最大的内存区域,进行垃圾回收的主要区域。 - **栈内存**:每个线程都有自己的程序计数器、虚拟机栈、...

      jvm.rar_jvm

      本文将深入探讨JVM管理手册中的关键知识点,包括内存管理、垃圾回收机制以及JVM调优。 首先,我们需要理解JVM内存结构。在JVM中,内存被划分为几个主要区域,包括堆(Heap)、栈(Stack)、方法区(Method Area)、...

      JVM高级特性与最佳实践(第2版)源代码.zip

      - 通过监控和日志分析进行性能瓶颈定位。 - 通过代码优化减少内存占用,提升应用响应速度。 通过这本书的源代码,读者可以深入理解上述每个知识点的实际应用,结合实际案例,有助于提高对JVM的理解和掌握,进一步...

      实战Java虚拟机 JVM故障诊断与性能优化 葛一鸣

      例如,通过日志分析、堆转储分析(如使用MAT或Jhat工具)、线程Dump分析来定位问题原因。 6. **源代码分析**:书中提到的“原书code”可能包含了作者为解释理论知识而编写的示例代码。通过阅读和分析这些代码,读者...

      jvm解析编译过的class文件

      同时,通过分析JVM的内存快照和日志,可以定位和解决内存泄漏、性能瓶颈等问题。 总的来说,JVM解析编译过的class文件是一个复杂的过程,涉及众多细节。开发者不仅要理解编译过程,还需要熟悉JVM的内部机制,才能更...

      实战JAVA虚拟机 (JVM故障诊断与性能优化)【含源码】

      例如,双亲委派模型是如何保证类加载的安全性和有序性的,如何利用JVM的内存配置避免OutofMemoryError,以及如何通过线程栈分析定位并发问题。这些内容对于理解和解决实际项目中的性能瓶颈至关重要。 JVM故障诊断是...

      jvm高级特性与最佳实践(第二版)

      通过对GC日志、内存快照等数据的分析,可以对应用程序的性能瓶颈做出准确判断,并采取相应的优化措施。 在实际开发中,JVM的应用范围非常广泛。本书不仅讨论了JVM在服务器端的应用,还包括JVM在移动端(如Android)...

      实战JAVA虚拟机 JVM故障诊断与性能优化

      8. **故障诊断**:通过日志分析、堆转储分析(如使用MAT工具)、线程Dump分析等手段,定位和解决内存泄漏、死锁、性能瓶颈等问题。 9. **JIT编译器**:JVM包含解释器和Just-In-Time编译器,后者可以将热点代码编译...

      JVM夺命连环问面试题分享给需要的同学.docx

      什么是安全点,什么是安全区域? 如果CPU使用率突然飙升,你会怎么排查? CMS、G1垃圾回收期中的三色表计你了解吗? 讲一讲类加载与类加载器 什么是双亲委派机制?它有什么作用? G1收集器有哪些特点? 你有哪些手段...

      JVM.pdf_jvm_

      **Java虚拟机(JVM)概述** ...了解并掌握这些JVM相关知识点,不仅能帮助开发者解决实际问题,也是面试中必不可少的部分。通过深入学习JVM的工作原理和调优技巧,可以提升Java应用的性能和稳定性。

      jvm 调优笔记-jvm.zip

      《JVM调优笔记》 Java虚拟机(JVM)是Java...以上内容仅是JVM调优的一部分,实际调优过程需要结合应用特点和性能指标进行细致分析和实验。在实践中,理解JVM的工作原理,结合监控和日志,才能制定出合适的调优策略。

      Java面试知识点解析-JVM.zip

      - **日志与堆转储**:通过-XX:+HeapDumpOnOutOfMemoryError参数生成堆转储文件,用于分析内存泄漏。 6. **类加载双亲委派模型**: 类加载时,先由父加载器尝试加载,只有父加载器无法加载时,子加载器才会尝试。 ...

    Global site tag (gtag.js) - Google Analytics