JAVA虚拟机垃圾回收机制和JAVA排错三剑客

简介:

一、Java虚拟机逻辑回收机制

1、Java垃圾回收器

        Java垃圾回收器是Java虚拟机(JVM)的三个重要模块(另外两个是解释器和多线程机制)之一,为应用程序提供内存的自动分配(Memory Allocation)、自动回收(Garbage Collect)功能,这两个操作都发生在Java堆上(一段内存快)。

        某一个时点,一个对象如果有一个以上的引用(Rreference)指向它,那么该对象就为活着的(Live),否则死亡(Dead),视为垃圾,可被垃圾回收器回收再利用。

        回收操作需要消耗CPU、线程、时间等资源,所以容易理解的是垃圾回收操作不是实时的发生(对象死亡马上释放),当内存消耗完或者是达到某一个指标(Threshold,使用内存占总内存的比列,比如0.75)时,触发垃圾回收操作。有一个对象死亡的例外,java.lang.Thread类型的对象即使没有引用,只要线程还在运行,就不会被回收。

        依据统计分析可知,Java(包括一些其它高级语言)里面大多数对象生命周期都是短暂的,所以把Java内存分代管理。分代的目的无非就是为不同代的内存块运用不同的管理策略(算法),从而最大化性能。相对于年老代,通常年轻代要小很多,回收的频率高,速度快。年老代则回收频率低,耗时长。内存在年轻代里面分配,年轻代里面的对象经过多个回收周期依然存活的会自动晋升到年老代。

2、垃圾回收类型

    所有的回收器类型都是基于分代技术。Java HotSpot虚拟机包含三代,年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation)。

(1)永久代

    存储类、方法以及它们的描述信息。可以通过-XX:PermSize=64m和-XX:MaxPermSize=128m两个可选项指定初始大小和最大值。通常 我们不需要调节该参数,默认的永久代大小足够了,不过如果加载的类非常多,不够用了,调节最大值即可。

(2)年老代

    主要存储年轻代中经过多个回收周期仍然存活从而升级的对象,当然对于一些大的内存分配,可能也直接分配到永久代(一个极端的例子是年轻代根本就存不下)。

(3)年轻代

    绝大多数的内存分配回收动作都发生在年轻代。如下图所示, 年轻代被划分为三个区域,原始区(Eden)和两个小的存活区(Survivor),两个存活区按功能分为From和To。绝大多数的对象都在原始区分配,超过一个垃圾回收操作仍然存活的对象放到存活区。

        说明:年轻代里面的对象经过多个回收周期依然存活的会自动晋升到年老代。年老代多个回收周期依然存活的会成为永久代。

3、JAVA虚拟机垃圾回收机制

 (1)Minor GC

    从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC。这一定义既清晰又易于理解。但是,当发生Minor GC事件的时候,当 JVM 无法为一个新的对象分配空间时会触发 Minor GC,比如当 Eden 区满了。所以分配率越高,越频繁执行 Minor GC。


        所有的 Minor GC 都会触发“全世界的暂停(stop-the-world)”即停止应用程序的线程。


 (2)Major GC vs Full GC

    指发生在老年代的 GC,出现了 Major GC,经常会伴随至少一次的 Minor GC 。MajorGC 的速度一般会比 Minor GC 慢 10倍以上。

    当发生Full GC时,也会触发“全世界的暂停(stop-the-world)”即停止应用程序的线程。并且持续时间长。

二、Java排错三剑客

1、jstack  查看指定的java进程的线程栈的相关信息

jstack [-l] <pid>

jstack -F [-m] [-l] <pid>

-l:long listings,会显示额外的锁信息,因此,发生死锁时常用此选项

-m:混合模式,既输出java堆栈信息,也输出C/C++堆栈信息

-F:当使用“jstack -l PID"无响应,可以使用-F强制输出信息

   例子:

       (1)查看pid           

    ps aux|grep tomcat

    root       2745  0.6 19.0 2333928 190144 pts/0  Sl   08:58   3:57 /usr/java/jdk1.8.0_144/jre/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs=/usr/local/tomcat/endorsed -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start

    root       9424  0.0  0.0 112648   960 pts/0    S+   19:47   0:00 grep --color=auto tomcat

 可以看到pid为 2745

    (2)jstack -l 2745

image.png

2、jstat  输出指定的java进程的统计信息   

jstat -help|-options

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

    # jstat -options

            -classclass loader  类加载统计

            -compilerJIT 编译统计

            -gcgc

            -gcnew新生代

            -gcold老年代

            -printcompilation JVM编译方法统计

        [<interval> [<count>]]

        interval时间间隔,单位是毫秒;

                count显示的次数;

     例子:

    (1)jstat -class 2745 1000 1000    以秒为间隔显示1000次,类加载统计

            image.png

        (2)jstat -gc 2745 1000 1000  可以看大GC和小GC的发生频率。

              image.png

    S0CS1CS0US1USurvivor 0/1区容量(Capacity)和使用量(Used)

    ECEUEden区容量和使用量

    OCOU年老代容量和使用量

    PCPU永久代容量和使用量

    YGCYGT年轻代GC次数和GC耗时

    FGCFGCTFull GC次数和Full GC耗时

    GCTGC总耗时

3、jmap  Memory Map, 用于查看堆内存的使用状态

        非常消耗资源,一般先把机器摘下,再执行命令

    jmap [option] <pid>  查看堆空间的详细信息:

    jmap -heap <pid>查看堆内存中的对象的数目:

    jmap -histo <pid>

    live只统计活动对象;

 保存堆内存数据至文件中,而后使用jvisualvm或jhat进行查看

    jmap -dump:<dump-options> <pid>

    dump -options:

    live dump only live objects; if not specified, all objects in the heap are dumped.

    format=b  binary format

    file=<file>  dump heap to <file>

    例子:jmap -dump:format=b,file=/app/dump  2745

            image.png

            cd /app

            因为是二进制文件不能直接看,需要转换

            jhat  dump   

            ss -ntl  会监听7000端口,可以在浏览器查看

            image.png



本文转自 hawapple 51CTO博客,原文链接:http://blog.51cto.com/guanm/2044858

相关文章
|
17天前
|
Oracle Java 关系型数据库
java体系结构和jvm
java体系结构和jvm
|
24天前
|
算法 Java
JVM垃圾回收机制
JVM垃圾回收机制
15 0
|
1月前
|
JavaScript 前端开发 算法
Java Script 中的垃圾回收机制有哪些缺点
Java Script 中的垃圾回收机制有哪些缺点
13 0
|
1月前
|
存储 Java 数据安全/隐私保护
【JVM】Java虚拟机栈(Java Virtual Machine Stacks)
【JVM】Java虚拟机栈(Java Virtual Machine Stacks)
36 0
|
28天前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
79 0
|
2天前
|
Java
Java 与垃圾回收有关的方法
Java 与垃圾回收有关的方法
|
3天前
|
监控 Ubuntu Java
Java VisualVM远程监控JVM
Java VisualVM远程监控JVM
Java VisualVM远程监控JVM
|
10天前
|
存储 缓存 监控
Java内存管理:垃圾回收与内存泄漏
【4月更文挑战第16天】本文探讨了Java的内存管理机制,重点在于垃圾回收和内存泄漏。垃圾回收通过标记-清除过程回收无用对象,Java提供了多种GC类型,如Serial、Parallel、CMS和G1。内存泄漏导致内存无法释放,常见原因包括静态集合、监听器、内部类、未关闭资源和缓存。内存泄漏影响性能,可能导致应用崩溃。避免内存泄漏的策略包括代码审查、使用分析工具、合理设计和及时释放资源。理解这些原理对开发高性能Java应用至关重要。
|
1月前
|
存储 缓存 安全
[Java基础]——JVM内存模型
[Java基础]——JVM内存模型
|
1月前
|
算法 Java UED
【JVM】分代收集算法:提升Java垃圾回收效率
【JVM】分代收集算法:提升Java垃圾回收效率
22 0