利用java虚拟机的工具jmap分析java内存情况

news/2024/7/2 23:02:17

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

有时候碰到性能问题,比如一个java application出现out of memory,出现内存泄漏的情况,再去修改bug可能会变得异常复杂,利用工具去分析整个java application 内存占用情况,然后再去走查代码。

首先先看一下,java内存分配的基本模型,由于JVM内存划分比较复杂,这里只是简单的说一下java内存划分

160813_kvqM_3721784.png

java 堆(heap):

Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的

唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC 堆”

所以Java 堆中还可以细分为:新生代和老年代;

新生代:所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。

老年代(old Generation):在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象

持久代(Prem Generation):用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=<N>进行设置。

再细致一点的有Eden 空间、From Survivor 空间、To Survivor 空间等。如果从内存分配

的角度看,线程共享的Java 堆中可能划分出多个线程私有的分配缓冲区(Thread Local

Allocation Buffer,TLAB)。不过,无论如何划分,都与存放内容无关,无论哪个区域,

存储的都仍然是对象实例,进一步划分的目的是为了更好地回收内存,或者更快地分配内存。

 

java 栈区:

JVM中运行的每个线程都拥有自己的线程栈,线程栈包含了当前线程执行的方法调用相关信息,我们也把它称作调用栈。随着代码的不断执行,调用栈会不断变化。

一般认为 方法,局部变量,对象的引用 都是存在栈区内的。

java方法区:

方法区(Method Area)与Java 堆一样,是各个线程共享的内存区域,它用于存

储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

很多人称之为永生代(Permanent Generation);

出现out of memory 接着会出现 java heap space,这种情况是堆空间满了,

可能出现的情况,比如一个方法 进栈了,里面有一段逻辑,最常见的就是打个比方

public void method(){

     List<Model> list=...;

  .... 执行代码的逻辑

 }

这个list 里面有N多对象,但是执行下面的逻辑时内存溢出,这是因为方法在没有出栈之前,java heap中的对象太多(方法在出栈之后GC 对 没有引用的 对象进行垃圾回收)。

还有 就是有一些全局的变量或者集合 ,或者存在方法区的 内存 没有进行及时清理,导致内存没有释放,这种称之为真泄漏。

2.1 利用jmap 进行内存分析,

jmap -heap pid //打印heap空间的概要,这里可以粗略的检验heap空间的使用情况。

Heap Configuration:指java应用启动时设置的JVM参数。像最大使用内存大小,年老代,年青代,持久代大小等。

Heap Usage:当时的heap实际使用情况。包括新生代、老生代和持久代。

其中新生代包括:Eden区的大小、已使用大小、空闲大小及使用率。Survive区的From和To同样。

有这个可以很简单的查看本进程的内存使用情况。

可以用于分析堆内存分区大小是否合理,新生代和老生代的大小分配是否合适等。

也许进程占用的总内存比较多,但我们在这里可以看到真正用到的并没有多少,很多都是"Free"。内存使用的堆积大多在老年代,内存池露始于此,所以要格外关心“Old Generation”。

jmap -histo PID //这里会生成一个类的统计报表,此表非常简单,如显示什么类有多少个实例,共占了多少字节等。

2.2  利用jmap 生成dump 文件,然后再利用mat工具进行分析。

jmap -dump:live,format=b,file=‘文件名 ’2657 //2657 是进程的PID 号

生成转储文件之后,file -open(该转储文件)

164639_tSNP_3721784.png

 

上面的饼状图显示了内存分配的比例,通过dominator_tree可以看到详细信息。

 

 

转载于:https://my.oschina.net/u/3721784/blog/1605205


http://lihuaxi.xjx100.cn/news/239183.html

相关文章

oracle10g删除asm组,Oracle 10G RAC 删除已有节点

如果现在在RAC集群中有三个节点c1、c2、c3&#xff1a;如果想要卸载c3节点。1、在c1或者c2上删除c3实例运行dbca然后选择Oracle Real Application Clusters database选择Instance Management选择Delete an instance选择实例&#xff0c;填写用户名密码&#xff0c;Next选择c3: …

Vue.js双向绑定的实现原理

Vue.js 最核心的功能有两个&#xff0c;一是响应式的数据绑定系统&#xff0c;二是组件系统。本文仅探究双向绑定是怎样实现的。先讲涉及的知识点&#xff0c;再用简化得不能再简化的代码实现一个简单的 hello world 示例。 一、访问器属性 访问器属性是对象中的一种特殊属性&a…

迷宫出路代码_如何在软件开发的迷宫中找到自己的出路

迷宫出路代码by Tim Kleier蒂姆克莱尔(Tim Kleier) 如何在软件开发的迷宫中找到自己的出路 (How to find your way through the corn maze of software development) The corn maze is one of my favorite challenges to tackle. It’s an unnerving experience, especially w…

Oracle数据库联邦,使用联邦数据库将oracle表迁移到DB2(9.7)中的脚本说明

由于兄弟项目组要测试&#xff0c;需要将oracle中的表迁移到db2中&#xff0c;操作步骤如下&#xff1a;#1 在windows数据库中建联邦数据库服务器\用户映射connect to sampleCREATE WRAPPER DRDA LIBRARY db2drda.dll;--创建DB2包装器CREATE WRAPPER NET8 LIBRARY db2net8.dll;…

laravel5.4 关于数据填充的知识

需求&#xff1a;大量excel表格数据 集中整理到一个规定数据表中&#xff0c;并且增加新字段做标记步骤&#xff1a;把需要整理的excel表格提前存放到mysql数据库指定的表中 &#xff0c;可以用图形化工具来执行&#xff01; 核心&#xff1a;利用laravel5.4 框架自带的填充功能…

6.1.1 验证注解的使用

数据注解特性定义在名称空间System.ComponentModel.DataAnnotations 中(但接下来 将看到&#xff0c;有些特性不是定义在这个名称空间中)。它们提供了服务器端验证的功能&#xff0c;当在模 型的属性上使用这些特性之一时&#xff0c;框架也支持客户端验证。在名称空间DataAnno…

香草 jboss 工具_香草JavaScript中的记忆游戏

香草 jboss 工具by Marina Ferreira通过玛丽娜费雷拉(Marina Ferreira) 香草JavaScript中的记忆游戏 (Memory Game in Vanilla JavaScript) 在30分钟内构建一个记忆游戏&#xff0c;学习JS&#xff0c;CSS和HTML&#xff01; (Learn JS, CSS and HTML by building a memory ga…

织梦 新建 php arclist,织梦arclist按照自定义字段来调用相关文章

织梦arclist按照自定义字段来调用相关文章&#xff0c;这对于想要在首页调用某个自定义字段的文章的同学来讲&#xff0c;非常不错&#xff0c;接下来看教程打开 include aglibrclist.lib.php 找到&#xff1a;//时间限制(用于调用最近热门文章、热门评论之类)&#xff0c;这里…