美文网首页
Java虚拟机

Java虚拟机

作者: 93张先生 | 来源:发表于2019-11-21 22:28 被阅读0次

走进Java

JDK

Java程序设计语言, Java虚拟机,JavaAPI类库;JDK用于Java开发的最小环境;

JRE

Java虚拟机,JavaSEAPI,JRE是支持Java运行的标准环境;
JDK和JRE的区别:Java语言还有Java语言的调试工具和工具API;


image
2.Java内存区域与内存溢出异常
2.3虚拟机对象
2.3.1虚拟机对象创建过程

1.虚拟机遇到一个new指令时,先去检查这个指令的参数是否能在常量池中定位到一个类符号的运用,并检查这个符号引用代表的类是否已被加载,解析和初始化;如果没有必须执行类的加载过程.
2.为新生对象分配内存,对象所需内存大小在类加载完成可完全确定;分配内存方法:指针碰撞和空闲列表;指针碰撞应用于在垃圾回收带有压缩整理的功能;CMS(CONCURRENT MARK SWEEP)并发标记删除,采用空闲列表法;
3.线程安全下的内存空间分配:1.CAS配上失败重试的方式保证更新的原子性;2.把内存分配的动作按照线程划分在不同的空间之间进行;TLAB(Thread Local Allocation Buffer);
4.除对象头外,内存分配的空间都初始化为零;使未初始化时,也能访问到这些字段的数据类型所对应的零值;
5.初始化对象头:元数据信息,对象哈希码,对象的GC分代年龄,锁状态标志,等
6.从虚拟机的角度,一个新的对象已经产生,但从java程序角度对象刚刚创建,还没有执行init方法(),所有的字段还都是零值;

2.3.2对象的内存布局

对象包含三部分:
对象头:两部分:Mark Word自身的运行时数据:哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等;第二部分:类型指针,指向对象的元数据的指针;如果是数组,还会有数组大小;
实例数据:对象正真存储的有效信息;
对其填充:jvm自动内存管理要求对象的起始地址必须是8字节的整数倍;

2.3.3对象的访问

reference只规定了一个指向对象的引用;并没有定义通过何种方式去定位和访问堆中的对象;两种:句柄访问和直接指针访问;
句柄访问:句柄池:对象实例数据的指针和对象类型的指针;reference地址不用修改,直接修改实例数据指针,在垃圾回收非常频繁,只改变一个对象实例地址,reference指向地址不用修改;
直接指针访问:reference直接存储对象地址,对象里面还会有存储对象数据类型的指针;最大的好处是快,节省了一次指针定位的开销;Java存在大量的对象访问,积少成多,客观的开销;Java sun Hotspot 使用了直接指针访问;

2.4 实战 OutOfMemoryError异常
2.4.1 Java堆溢出

-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError 可以将虚拟机内存溢出信息dump当前的内存堆转储快照以便事后处理 最小值-Xms 最大值 -Xmx
出现问题
1.内存泄露:造成对象无法GC,查看GCRoots引用链,找到无法回收的对象,定位内存泄露代码位置;
2.内存对象确实还必须活着,重新设置虚拟机参数;
3.代码检查是否有生命周期过长,持有状态时间过长的情况,并优化;

public class HeapOOM {
    /**
         * -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError 可以将虚拟机内存溢出信息dump当前的内存堆转储快照以便事后处理 最小值-Xms 最大值 _Xmx
     *  堆内存溢出
     */
    static class OOMObject{}
    public static void main(String[] args) {
        List<OOMObject> list = new ArrayList<OOMObject>();
        while (true){
            list.add(new OOMObject());
        }
    }
}
2.4.2虚拟机栈和本地方法栈溢出

-Xss128k;
HotSpot虚拟机不区分虚拟机栈和本地方法栈; -Xoss参数无效设置本地方法栈无效;
StackOverflowError 线程请求的栈深度大于虚拟机所允许的最大深度;
OutOfMemoryError虚拟机在扩展栈时,无法申请足够的内存空间;
栈是线程私有的,栈内存大小一定,线程栈的越大,开辟的线程越少;栈帧大小影响着栈的大小;一般1000-2000栈帧没有问题;对于普通的递归操作能过满足;

2.4.3方法区和运行时常量池溢出

String.Intern()是一个Native方法;
如果字符串常量池存在一个等于string的字符串,则返回代表池中字符串的String对象;否则新建一个String对象放入常量池中,并返回String对象的引用;
JDK 1.7 已经把运行时常量池移除方法区
PermGen方法区
-XX:PermSize=10M -XX:MaxPermSize=10M 设置方法区大小;
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=10M; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=10M; support was removed in 8.0
-XX:MetaspaceSize=3M -XX:MaxMetaspaceSize=3M
Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
方法区主要存放Class相关信息;类名,访问修饰符,常量池,字段描述,方法描述;测试主要通过动态添加大量的类,进行测试;CGLib;
jdk1.8中,其实已经没有永久代这一说了,取而代之的是一个叫元空间(Meta space)。而常量池放到了堆中,所以也就不会出现PermGen space了
类的元数据, 字符串池, 类的静态变量将会从永久代移除, 放入Java heap或者native memory. 其中建议JVM的实现中将类的元数据放入native memory, 将字符串池和类的静态变量放入java堆中. 这样可以加载多少类的元数据就不在由MaxPermSize控制, 而由系统的实际可用空间来控制。

2.4.4本机直接内存溢出

-Xmx20M -XX:MaxDirectMemorySize=10M
默认值和堆的大小一样

3.垃圾收集器和内存分配策略

3.1概述

GC主要考虑:
哪些内存需要回收;
什么时候进行回收;
怎么回收;
不同区域的回收方式
线程私有的程序计数器,虚拟机栈,本地方法栈,随着线程的结束,内存回收;不用太多考虑;
回收主要是针对堆和方法区的回收;

3.2对象存活
3.2.1引用计数法

在对象中添加一个计数器,一个地方引用计数器+1,引用失效机计数器-1;为0时,对象不再使用,可以回收;
它的主要问题在于循环引用;还有并法修改对象header中的计数,可能造成混乱,若使用锁,可能效率变低;

/**
 * Author: wewe
 * Date:  19-3-24 下午4:52
 * Description:
 * 对象引用问题,假设是引用基数法,循环引用问题;
 * myObject1的引用计数为2,myObject2的引用计数也为2;
 * 对myObject1来说,一个main函数引用myObject1,myObject2.ref引用myObject1;所以计数是2;
 * 对myObject2来说,一个main函数引用myObject2,myObject1.ref引用myObject2;所以计数是2;
 * myObject1 = null; myObject2 = null;
 * 所以:
 * myObject1,只有了myObject2.ref引用;计数为1;
 * myObject2,只有了myObject1.ref引用;计数为1;
 * 此时myObject1和myObject2都没有在生存的必要了,应该回收,但他们相互引用;计数不为1;
 * 所以引用计数不能解决循环引用的问题;
 * 若要满足垃圾回收的条件,需要清除myObject2中的ref这个引用,
 * 而要清除掉这个引用的前提条件是myObject2引用的对象被回收,
 * 可是该对象的引用计数也为1,因为myObject1.ref指向了它。
 * 以此类推,也就进入一种死循环的状态。
 * Refer To:
 * https://blog.51cto.com/thatmonkey/1384463
 */
public class MyObject {
    public Object ref = null;
    public static void main(String[] args) {
        MyObject myObject1 = new MyObject();
        MyObject myObject2 = new MyObject();
        myObject1.ref = myObject2;
        myObject2.ref = myObject1;
        myObject1 = null;
        myObject2 = null;
    }
}
3.2.2可达性分析法

主流程序设计语言采用可达性分析作为判断对象是否存货的方法;

GCRoots 作为对象引用的起点,所走过的路径为引用链,GCRoots不可达,即可判定为可回收对象;

GC Roots:

1.虚拟机栈栈帧中本地变量表中引用的对象;

2.方法区中类静态属性引用的对象;

3.方法区中常量引用的对象;

4.本地方法栈中JNI(一般为Native方法)引用的对象;

https://blog.csdn.net/u010798968/article/details/72835255

3.2.3引用的分类

起始时,reference类型的数据中存储数值代表的是另一块内存的起始地址,就成这块内存代表着一个引用;

JDK1.2划分为强引用,软引用,弱引用,虚引用

强引用: Object o = new Object();这类强引用存在对象就不会被回收;

软引用:描述一些有用但并非必需的对象,对于他们在内存将要发生溢出之前,将这些对象列入回收范围之内进行第二次回收,第二次回收还是没有足够的内存,才会抛出内存溢出异常;

弱引用:被弱引用的对象只能存活到垃圾回收之前,在垃圾收集器工作时,弱引用都会被回收;

虚引用:虚引用的存在并不会影响对象的生存时间构成,它的唯一目的是,这个对象被收集器回收时,这个对象能收到一个系统的通知;

3.2.4生存还是死亡(finalize)

即使在可达性分析中不可达对象,也并非是"非死不可";这时处于"缓刑"阶段,至少经过两次标记过程,第一次可达性分析中,没有GCRoots相关联,进行标记;finalize方法没有被复写,也没有被执行,这时它是不会被标记的,ta就会从finalize中逃脱,只有执行了finalize(),才会被第二次标记为不可达;finalize()是逃离被回收的最后一次机会.

如果这个对象有必要执行finalize(),这个对象放入F-Queue的队列中,并稍后由虚拟机自动建立的,优先级低的Finalize线程去执行;对象在finalize()方法中--只要重新与引用链上的任何一个对象建立关联即可;比如把自己this赋值给类变量或者对象 的成员变量,那么就会在第二次标记时,它将被移除"即将回收"的集合;finalize()只会被系统调用一次;最好不要使用fianlize()方法,请忘掉,使用try-finally

3.2.5回收方法区(1.7已经没有方法区了)

方法区(永久代)回收是存在的,效率比较低,堆中的新生代可以达到70%-95%;

永久代主要回收:废弃的常量和无用的类

废弃常量:常量池中不存在引用的常量,比如"abc"

无用类:

1.该类的所有实例都已经被回收,也就是Java堆中不存在任何该类的任何实例;

2.加载该类的ClassLoader已经被回收;

3.该类对应的java.lang.Class对象没有被任何地方引用,无法在任何地方通过反射访问该类的方法;

类的元信息放入了metaspace,字符串池和类的静态变量放入java堆中;

3.3垃圾收集算法
3.3.1标记-清除算法

Mark-Swap 分为两个阶段:标记和清除;

缺点:效率低下,产生内存碎片;


垃圾处理.png

图1中的(1)部分显示了随着程序的运行而分配出一些对象的状态,一个对象可以对其他的对象进行引用。

图中(2)部分中,GC开始执行,从根开始对可能被引用的对象打上“标记”。大多数情况下,这种标记是通过对象内部的标志(Flag)来实现的。于是,被标记的对象我们把它们涂黑。

图中(3)部分中,被标记的对象所能够引用的对象也被打上标记。重复这一步骤的话,就可以将从根开始可能被间接引用到的对象全部打上标记。到此为止的操作,称为标记阶段(Mark phase)。

标记阶段完成时,被标记的对象就被视为“存活”对象。

图1中的(4)部分中,将全部对象按顺序扫描一遍,将没有被标记的对象进行回收。这一操作被称为清除阶段(Sweep phase)。

在扫描的同时,还需要将存活对象的标记清除掉,以便为下一次GC操作做好准备。标记清除算法的处理时间,是和存活对象数与对象总数的总和相关的。

参考:https://segmentfault.com/a/1190000004665100#articleHeader6

3.3.2复制算法

复制算法开辟两块大小相同的空间;解决了效率问题,内存碎片问题;只有原来的标记过程,然后就将标记的对象复制到新的内存空间中去;

堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。

堆的内存模型大致为:

A1型2.png

默认的,新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 ),即:新生代 ( Young ) = 1/3 的堆空间大小。

老年代 ( Old ) = 2/3 的堆空间大小。其中,新生代 ( Young ) 被细分为 Eden 和 两个 Survivor 区域,这两个 Survivor 区域分别被命名为 from 和 to,以示区分。

默认的,Edem : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定 ),即: Eden = 8/10 的新生代空间大小,from = to = 1/10 的新生代空间大小。

JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块 Survivor 区域是空闲着的。

因此,新生代实际可用的内存空间为 9/10 ( 即90% )的新生代空间。

新生代是 GC 收集垃圾的频繁区域。

当对象在 Eden ( 包括一个 Survivor 区域,这里假设是 from 区域 ) 出生后,在经过一次 Minor GC 后,如果对象还存活,并且能够被另外一块 Survivor 区域所容纳

( 上面已经假设为 from 区域,这里应为 to 区域,即 to 区域有足够的内存空间来存储 Eden 和 from 区域中存活的对象 ),则使用复制算法将这些仍然还存活的对象复制到另外一块 Survivor 区域 ( 即 to 区域 ) 中,然后清理所使用过的 Eden 以及 Survivor 区域 ( 即 from 区域 ),并且将这些对象的年龄设置为1,以后对象在 Survivor 区每熬过一次 Minor GC,就将对象的年龄 + 1,当对象的年龄达到某个值时 ( 默认是 15 岁,可以通过参数 -XX:MaxTenuringThreshold 来设定 ),这些对象就会成为老年代。

但这也不是一定的,对于一些较大的对象 ( 即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代。

当Survivior空间不够使用,老年代进行分配担保;就是需要在老年代直接开辟空间;

3.3.3标记-整理算法

Mark-Compact,标记然后整理,让存活的对象向一端移动.然后清除其他对象;

3.3.4分代收集算法

Generational Collection;

新生代每次垃圾收集都有大批对象死去,只有少量的存活,选用复制算法;

老年代,对象存活率比较高,没有额外的外存空间进行担保,使用标记-清理或者标记-整理算法;

3.4HotSpot的算法实现
3.4.1枚举根节点
3.4.2安全点
3.4.3安全区域
3.5垃圾收集器

https://crowhawk.github.io/2017/08/15/jvm_3/

3.5.1Serial收集器
3.5.2ParNew收集器
3.5.3Parallel Scavenge收集器
3.5.4Serial Old收集器
3.5.5Parallel Old收集器
3.5.6CMS收集器
3.5.7G1收集器
3.5.8理解GC日志
3.5.9垃圾收集器参数总结

Serial parNew parallel Scavenge (高吞吐量,GC自动调节)

Serial Old parallel Old CMS (标记清除)

3.6内存分配与回收策略

7虚拟机类加载机制

7.1类加载的时机

1.遇到New getstatic putstatic invokestatic 这4条字节码指令时,类没有进行过初始化,则需要进行初始化;

7.2类加载的机制

https://blog.csdn.net/ns_code/article/details/17881581

4 虚拟机性能监控和故障处理

1.jps 虚拟机状态工具
jps -l -m -v
-q 只输出LVMID
-m 输出传入给主类main()方法的参数
-l 主类的全名,执行jar包的 输出jar 路径
-v 虚拟机启动时,jvm参数

wewe@wewe-ThinkPad-T580 ~/installSoftware/java/jdk1.8.0_161/bin $ jps -q
5220
5606
7623
7609


wewe@wewe-ThinkPad-T580 ~/installSoftware/java/jdk1.8.0_161/bin $ jps -l
5220 com.intellij.idea.Main
5606 org.jetbrains.idea.maven.server.RemoteMavenServer
7623 com.wewe.timeLoggerExample.DemoExample
7609 org.jetbrains.jps.cmdline.Launcher
8714 sun.tools.jps.Jps
3547 sun.tools.jconsole.JConsole

wewe@wewe-ThinkPad-T580 ~/installSoftware/java/jdk1.8.0_161/bin $ jps -m
9040 Jps -m
5220 Main
5606 RemoteMavenServer
7623 DemoExample
7609 Launcher /home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/javac2.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/netty-all-4.1.13.Final.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/resources_en.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/jdom.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/nanoxml-2.2.3.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/forms_rt.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/httpclient-4.5.2.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/jps-builders.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/snappy-in-java-0.5.1.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/openapi.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/jgoodies-forms.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/jna-platform.jar:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/jps-builders-6.jar:/home/wewe/installSoftw
3547 JConsole

wewe@wewe-ThinkPad-T580 ~/installSoftware/java/jdk1.8.0_161/bin $ jps -v
5220 Main -Xbootclasspath/a:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/boot.jar -Xms128m -Xmx750m -XX:ReservedCodeCacheSize=240m -XX:+UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=50 -ea -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true -XX:+HeapDumpOnOutOfMemoryError -XX:-OmitStackTraceInFastThrow -Dawt.useSystemAAFontSettings=lcd -Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine -XX:ErrorFile=/home/wewe/java_error_in_IDEA_%p.log -XX:HeapDumpPath=/home/wewe/java_error_in_IDEA.hprof -Didea.paths.selector=IntelliJIdea2017.3 -Djb.vmOptionsFile=/home/wewe/installSoftware/idea/idea-IU-173.3727.127/bin/idea64.vmoptions -Didea.jre.check=true
5606 RemoteMavenServer -Djava.awt.headless=true -Didea.version==2017.3 -Xmx768m -Didea.maven.embedder.version=3.3.9 -Dfile.encoding=UTF-8
7623 DemoExample -Dvisualvm.id=12437612211291 -javaagent:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/lib/idea_rt.jar=39623:/home/wewe/installSoftware/idea/idea-IU-173.3727.127/bin -Dfile.encoding=UTF-8
2.jstat 虚拟机统计信息监控工具
jstat -class 14117
Loaded  Bytes  Unloaded  Bytes     Time   
   580  1155.6        0     0.0       0.13

jstat -gc 14117
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
512.0  512.0   32.0   0.0   28672.0  21681.9   83456.0     905.1    4864.0 3641.6 512.0  393.6     302    0.731   0      0.000    0.731

jstat -compiler 14117
Compiled Failed Invalid   Time   FailedType FailedMethod
     301      0       0     2.76          0             


jstat -gc 14117 2000 20
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
512.0  512.0  192.0   0.0   23552.0  21063.3   83456.0     905.1    4864.0 3641.6 512.0  393.6    1121    2.661   0      0.000    2.661
512.0  512.0   0.0    96.0  32256.0   6671.7   83456.0     905.1    4864.0 3641.6 512.0  393.6    1127    2.681   0      0.000    2.681
512.0  512.0   0.0    96.0  29184.0  24135.7   83456.0     905.1    4864.0 3641.6 512.0  393.6    1133    2.693   0      0.000    2.693
512.0  512.0  128.0   0.0   38912.0  19924.6   83456.0     905.1    4864.0 3641.6 512.0  393.6    1140    2.716   0      0.000    2.716
512.0  512.0   0.0   128.0  43008.0  10537.5   83456.0     905.1    4864.0 3641.6 512.0  393.6    1145    2.729   0      0.000    2.729
512.0  512.0   0.0    96.0  38912.0  27059.8   83456.0     905.1    4864.0 3641.6 512.0  393.6    1149    2.739   0      0.000    2.739
512.0  512.0   0.0   128.0  34816.0  21329.9   83456.0     905.1    4864.0 3641.6 512.0  393.6    1155    2.751   0      0.000    2.751
512.0  512.0   0.0    96.0  31744.0  17662.0   83456.0     905.1    4864.0 3641.6 512.0  393.6    1161    2.765   0      0.000    2.765
512.0  512.0   0.0    64.0  28672.0   3797.0   83456.0     905.1    4864.0 3641.6 512.0  393.6    1167    2.780   0      0.000    2.780
    
3.jmap 内存映像工具
wewe@wewe-ThinkPad-T580 ~/installSoftware/java/jdk1.8.0_161/bin $ jmap -dump:live,format=b,file=jwei.hprof 14117
Dumping heap to /home/wewe/installSoftware/java/jdk1.8.0_161/bin/jwei.hprof ...
File exists

wewe@wewe-ThinkPad-T580 ~ $ jmap -finalizerinfo 4814
Attaching to process ID 4814, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12
Number of objects pending for finalization: 0

wewe@wewe-ThinkPad-T580 ~ $ jmap -heap 4814
Attaching to process ID 4814, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 2021654528 (1928.0MB)
   NewSize                  = 42467328 (40.5MB)
   MaxNewSize               = 673710080 (642.5MB)
   OldSize                  = 85458944 (81.5MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 24117248 (23.0MB)
   used     = 7827088 (7.4644927978515625MB)
   free     = 16290160 (15.535507202148438MB)
   32.4543165123981% used
From Space:
   capacity = 524288 (0.5MB)
   used     = 65536 (0.0625MB)
   free     = 458752 (0.4375MB)
   12.5% used
To Space:
   capacity = 524288 (0.5MB)
   used     = 0 (0.0MB)
   free     = 524288 (0.5MB)
   0.0% used
PS Old Generation
   capacity = 85458944 (81.5MB)
   used     = 902208 (0.86041259765625MB)
   free     = 84556736 (80.63958740234375MB)
   1.0557209787193251% used

1034 interned Strings occupying 69848 bytes.

wewe@wewe-ThinkPad-T580 ~ $ jmap -histo 4814

 num     #instances         #bytes  class name
----------------------------------------------
   1:         69269        3994080  [C
   2:         24183        1160784  java.nio.HeapCharBuffer
   3:           316         718256  [I
   4:         20892         501408  java.lang.String
   5:         18136         435264  java.lang.StringBuilder
   6:           666          75824  java.lang.Class
   7:           722          42248  [Ljava.lang.Object;
   8:          1245          39840  java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
   9:           167          37000  [B
  10:          1088          26112  java.util.LinkedList$Node
  11:           743          23776  java.util.HashMap$Node
  12:           293          18752  java.net.URL
4.jhat 虚拟机堆转储快照分析
wewe@wewe-ThinkPad-T580 ~/installSoftware/java/jdk1.8.0_161/bin $ jhat -J-Xmx512m jwei.hprof 
Reading from jwei.hprof...
Dump file created Tue Jun 18 17:39:11 CST 2019
Snapshot read, resolving...
Resolving 13945 objects...
Chasing references, expect 2 dots..
Eliminating duplicate references..
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
all-classes.png
5.jstack 生成虚拟机当前线程快照
jstack -l 4814 | more
wewe@wewe-ThinkPad-T580 ~/installSoftware/java/jdk1.8.0_161/bin $ jstack -l 4814 | more
2019-06-18 18:34:16
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode):

"Attach Listener" #32 daemon prio=9 os_prio=0 tid=0x00007ff89c001000 nid=0x17bb waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None

http://www.importnew.com/23761.html

相关文章

网友评论

      本文标题:Java虚拟机

      本文链接:https://www.haomeiwen.com/subject/zcyxwctx.html