JAVA虚拟机垃圾回收机制和JAVA排错三剑客-阿里云开发者社区

开发者社区> 科技小能手> 正文

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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java虚拟机定义
<div class="mod-top" id="card-container" style="margin-bottom:18px; font-family:arial,宋体,sans-serif; font-size:14px; line-height:24px"> <div class="card-summary nslog-area clearfix" style="line-h
1482 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
7749 0
Java虚拟机定义
虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。[1]  中文名 java虚拟机
1238 0
深入Java虚拟机——类型装载、连接(转)
来自http://hi.baidu.com/holder/item/c38abf02de14c7d31ff046e0     Java虚拟机通过装载、连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用。
895 0
SAP ECC7 SR3,BW7装一起的虚拟机,自学SAP BW的最佳学习
http://item.taobao.com/item.htm?id=13242988366
767 0
23706
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载