在上一次【https://www.cnblogs.com/webor2006/p/10629889.html】已经编写了一个能在堆空间出现内存溢出的代码,先来回顾一下:

其中咱们给JVM配置了如下参数:

其中还设置了一个当发生内存溢出时来将内存的信息给dump出来,其实就类似于Android中来分析内存也是需要dump内存信息一样,如下:

其dump出来的文件在这个目录之下:

其实这个dump出来的文件也叫做“转储”文件,那用何工具来分析呢,有很多工具可以分析,这里学习一下之前也介绍的jvisualvm,它是由oracle基于hospot虚拟机力推的一个集大成者的一个功能超级强大的图形化分析工具,它是集成了很多的命令行的工具使得我们在一个GUI上看到不管是正在运行的JVM进程的种种信息,包括线程的信息、元空间的信息,堆空间的信息等等,还可以分析我们dump出来的转储文件,所以咱们先来打开此工具,在命令行中输入:

接下来咱们来打开转储文件:

接下来就详细来分析一下该转储文件:

  1. 堆转储上的线程:
  2.  
  3. "main" prio=5 tid=1 RUNNABLE
  4. at java.lang.OutOfMemoryError.<init>(OutOfMemoryError.java:48)
  5. at java.util.Arrays.copyOf(Arrays.java:3210)
  6. Local Variable: class java.lang.Object[]
  7. at java.util.Arrays.copyOf(Arrays.java:3181)
  8. Local Variable: java.lang.Object[]#301
  9. at java.util.ArrayList.grow(ArrayList.java:265)
  10. at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
  11. at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
  12. at java.util.ArrayList.add(ArrayList.java:462)
  13. Local Variable: com.jvm.memory.MyTest1#64646
  14. at com.jvm.memory.MyTest1.main(MyTest1.java:11)
  15. Local Variable: java.util.ArrayList#7
  16.  
  17. "Finalizer" daemon prio=8 tid=3 WAITING
  18. at java.lang.Object.wait(Native Method)
  19. at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
  20. at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
  21. Local Variable: java.lang.ref.ReferenceQueue#26
  22. at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:212)
  23. Local Variable: java.lang.System$2#1
  24.  
  25. "Signal Dispatcher" daemon prio=9 tid=4 RUNNABLE
  26.  
  27. "Reference Handler" daemon prio=10 tid=2 WAITING
  28. at java.lang.Object.wait(Native Method)
  29. at java.lang.Object.wait(Object.java:502)
  30. at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
  31. at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

可以清晰的看到线程的具体异常信息,其中OutOfMemoryError异常如果在真实项目中出现了肯定就是大问题了,对于它其实都比较熟悉了,还是来瞅一下它的官方对它的解释:

其中该异常的继承体系如下 :

好,再回到jvisualvm,目前咱们是在这个视图上看到的信息:

接着来切换到类瞅一下:

好,接下来再来看另外一个视图:

也就是说需要在类视图中来选择要查看的实例数,所以咱们回到类视图来操作一下:

此时就可以自动跳到实例数这个视图了,如下:

而在实例数视图左侧看到有个500个实例的提示:

貌似跟我们在类似图看到个数不一样啊:

其实不是500个,还有其它木有展开而已,如下:

接着点击一下其中的实例,在右侧可以看到具体的字段信息,如下:

然后还能看到类加载器相关的信息,很显然我们自己创业的类是由应用类加载器所加载的:

接着还可以看一下它的父加载器,很显然是由扩展类加载器加载的:

而它的父加载器很显然就是根类加载器,也就是null嘛:

进一步对咱们之前学习的类加载器相关的知识进行巩固,好,再看最后一下视图:

接下来咱们再来改造一下我们的程序:

咱们先来看一下gc()方法的官方解释:

它最终调用的是System类中的gc(),如下:

咱们再来瞅下它的gc()注释:

从上面的解释也就说明了为啥在实际项目中不鼓励手动去调这个gc()方法,咱们这样做目的是为了学习研究仅此而已,当手动调用了gc()之后程序内部发生了啥变化呢?这里还是借用jvisualvm来查看下,首先找到咱们运行的进程:

然后双击打开它:

也有几个视图,咱们一个个来瞅下,先来看下监视:

可见是实时对进程的情况进行监视的,咱们细看一下:

接下来再切一个视图:

然后再切另外一个视图:

最后一个视图是用来分析性能的:

大致了解下既可,这里我们从jvisualvm的分析中可以发现我们的程序在堆中的使用基本是维持在2MB左右的,如下:

那。。如果我们手动将JVM的堆内存由目前的5MB改成1MB呢,看我们程序虽说主动调用了gc()看是否还会有溢出出现,试一下:

其实很容易理解,我们设置的堆内存是在1MB,而实际我们程序堆内存会在2MB左右,当然会溢出啦。

实战jvisualvm的更多相关文章

  1. 深入理解JVM(学习过程)

    这,仅是我学习过程中记录的笔记.确定了一个待研究的主题,对这个主题进行全方面的剖析.笔记是用来方便我回顾与学习的,欢迎大家与我进行交流沟通,共同成长.不止是技术. 2020年02月06日22:43:0 ...

  2. JVisualVM简介与内存泄漏实战分析

    JVisualVM简介与内存泄漏实战分析 学习了:https://blog.csdn.net/kl28978113/article/details/53817827

  3. 使用jvisualvm.exe 的Btrace插件介绍/使用教程

    一.背景        在生产环境中可能经常遇到各种问题,定位问题需要获取程序运行时的数据信息,如方法参数.返回值.全局变量.堆栈信息等.为了获取这些数据信息,我们可以 通过改写代码,增加日志信息的打 ...

  4. 项目实战8—tomcat企业级Web应用服务器配置与会话保持

    tomcat企业级Web应用服务器配置与实战 环境背景:公司业务经过长期发展,有了很大突破,已经实现盈利,现公司要求加强技术架构应用功能和安全性以及开始向企业应用.移动APP等领域延伸,此时原来开发w ...

  5. jvm本地实战

    前言 ​ 由于上次线上full gc,让我这个没有机会实战接触jvm的人,尝到了一定的甜头,同时也觉得自己还有很多东西需要去实战并总结.这是一篇记录jvm配置参数,使用jvisualvm工具来让人对j ...

  6. jvisualvm工具使用

    VisualVM 是Netbeans的profile子项目,已在JDK6.0 update 7 中自带(java启动时不需要特定参数,监控工具在bin/jvisualvm.exe). https:// ...

  7. 项目实战8.1—tomcat企业级Web应用服务器配置与会话保持

    分类: Linux架构篇   tomcat企业级Web应用服务器配置与实战 环境背景:公司业务经过长期发展,有了很大突破,已经实现盈利,现公司要求加强技术架构应用功能和安全性以及开始向企业应用.移动A ...

  8. jvisualvm 工具使用

    VisualVM 是Netbeans的profile子项目,已在JDK6.0 update 7 中自带(java启动时不需要特定参数,监控工具在bin/jvisualvm.exe). https:// ...

  9. 转 jvisualvm 工具使用 https://www.cnblogs.com/kongzhongqijing/articles/3625340.html

    VisualVM 是Netbeans的profile子项目,已在JDK6.0 update 7 中自带(java启动时不需要特定参数,监控工具在bin/jvisualvm.exe). https:// ...

随机推荐

  1. 高级UI-TableLayout

    TableLayout选项卡,用于需要使用选项卡的场景,一般是用于切换Fragment,现在的主流做法一般是TableLayout+ViewPager+Fragment,综合实现选项卡的操作 由于Ta ...

  2. 利用卷积神经网络处理cifar图像分类

    这是一个图像分类的比赛CIFAR( CIFAR-10 - Object Recognition in Images ) 首先我们需要下载数据文件,地址: http://www.cs.toronto.e ...

  3. php实现文件与16进制相互转换

    php实现文件与16进制相互转换 <pre><?php/** * php 文件与16进制相互转换 * Date: 2017-01-14 * Author: fdipzone * Ve ...

  4. js获取下拉框的值

      获取select 选中的option的值: $("#ddlRegType").find("option:selected").val(); 获取select ...

  5. Zero-shot Learning / One-shot Learning / Few-shot Learning

    Zero-shot Learning / One-shot Learning / Few-shot Learning Learning类型:Zero-shot Learning.One-shot Le ...

  6. python基础学习(十)

    21.文件操作 # r只读 w只写(原来文件会消失!!!,也可以创建新文件) a追 # 加 r+ 读写 story_file = open("Story.txt", "r ...

  7. (一)Spring Security Demo 登陆与退出

    文章目录 配置springSecurityFilterChain过滤器 配置身份验证 加载配置 登陆项目 退出 下面的代码需要spring环境的支持: 看这个系列博客之前,需要这个博客,大概了解下 s ...

  8. 剑指offer13:数组[奇数,偶数],奇数偶数相对位置不变。

    1. 题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 2. 思路和方 ...

  9. Redis--zset类型操作命令

    有序集合类型 zset (sorted set ) redis 有序集合zset和集合set一样也是string类型元素的集合,且不允许重复的成员. 不同的是 zset 的每个元素都会关联一个分数(分 ...

  10. 玫瑰花小制作分享-JavaScript(七夕专属浪漫)

    分享一个玫瑰花的制作小方法,用小小的代码给自己的她送上一个不一样的玫瑰花. 玫瑰花代码由JavaScript实现,JavaScript 作为一种脚本语言, 被发明用于在 HTML 网页上使用,可以给H ...