JAVA内存分析指引201007_V0.2

合集下载

内存分析工具MAT的使用

内存分析工具MAT的使用

内存分析工具MAT的使用MAT(Memory Analyzer Tool)是一个开源的Java内存分析工具,可以帮助开发人员分析和优化Java应用程序的内存使用情况。

在开发和调试过程中,MAT可以帮助我们找到内存泄漏、大对象、重复对象以及内存使用高的地方,从而提高应用程序的性能和稳定性。

以下是使用MAT进行内存分析的一般步骤:2. 创建内存快照:在使用MAT进行内存分析之前,我们需要创建Java应用程序的内存快照。

可以通过以下几种方式创建内存快照:- 在Eclipse中启动的Java应用程序中,可以使用"Eclipse Memory Analyzer"菜单中的"Dump HPROF File"选项来创建内存快照。

- 在Java命令行应用程序中,可以通过添加JVM参数"-XX:+HeapDumpOnOutOfMemoryError"来在内存溢出错误发生时自动创建内存快照。

- 对于正在运行的Java进程,可以使用jmap命令手动创建内存快照。

3. 打开内存快照:启动MAT后,可以通过"File"菜单中的"Open Heap Dump"选项打开已经创建的内存快照。

MAT支持打开多种格式的内存快照文件,包括HPROF、IBM PHD、Eclipse MAT等。

4. 分析内存使用情况:在打开内存快照后,MAT会对内存进行解析和分析,并显示内存使用的概览信息。

在"Overview"选项卡中,我们可以查看内存占用的总大小、对象数量和最常见的对象类型。

5. 查找内存泄露:MAT提供了多种工具和视图,可以帮助我们找到内存泄漏的原因。

其中,"Leak Suspects"视图可以显示潜在的内存泄漏问题,"Path to GC Roots"视图可以展示垃圾回收根对象的引用链,帮助我们找到导致对象无法被回收的原因。

Java内存区域划分、内存分配原理

Java内存区域划分、内存分配原理

本文由我司收集整编,推荐下载,如有疑问,请与我司联系Java 内存区域划分、内存分配原理2014/11/16 2448 运行时数据区域Java 虚拟机在执行Java 的过程中会把管理的内存划分为若干个不同的数据区域。

这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,而有的区域则依赖线程的启动和结束而创建和销毁。

Java 虚拟机包括下面几个运行时数据区域:程序计数器程序计数器是一块较小的区域,它的作用可以看做是当前线程所执行的字节码的行号指示器。

在虚拟机的模型里,字节码指示器就是通过改变程序计数器的值来指定下一条需要执行的指令。

分支,循环等基础功能就是依赖程序计数器来完成的。

由于java 虚拟机的多线程是通过轮流切换并分配处理器执行时间来完成,一个处理器同一时间只会执行一条线程中的指令。

为了线程恢复后能够恢复正确的执行位置,每条线程都需要一个独立的程序计数器,以确保线程之间互不影响。

因此程序计数器是“线程私有”的内存。

如果虚拟机正在执行的是一个Java 方法,则计数器指定的是字节码指令对应的地址,如果正在执行的是一个本地方法,则计数器指定问空undefined。

程序计数器区域是Java 虚拟机中唯一没有定义OutOfMemory 异常的区域。

Java 虚拟机栈和程序计数器一样也是线程私有的,生命周期与线程相同。

虚拟机栈描述的是Java 方法执行的内存模型:每个方法被执行的时候都会创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息。

每一个方法被调用的过程就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。

java内存使用情况的命令

java内存使用情况的命令

java内存使用情况的命令Java是一种面向对象的编程语言,它在开发应用程序时需要使用内存来存储数据和执行代码。

因此,了解Java的内存使用情况对于开发人员来说是非常重要的。

Java虚拟机(JVM)负责管理Java应用程序的内存,它使用垃圾回收机制来自动管理内存的分配和释放。

JVM的内存可以分为以下几个部分:1. 堆(Heap):堆是Java程序运行时动态分配的内存区域,用于存储对象实例。

堆的大小可以通过命令行参数-Xmx和-Xms来设置。

-Xms表示JVM启动时初始分配的堆内存大小,-Xmx表示堆能够达到的最大内存大小。

2. 方法区(Method Area):方法区用于存储已加载的类信息、常量、静态变量等数据。

方法区的大小可以通过命令行参数-XX:PermSize和-XX:MaxPermSize来设置。

-XX:PermSize表示JVM启动时初始分配的方法区大小,-XX:MaxPermSize表示方法区能够达到的最大大小。

3. 栈(Stack):栈用于存储Java方法中的局部变量以及方法调用时的状态信息。

每个Java线程都有一个独立的栈,栈的大小是固定的,并且在线程创建时被分配。

栈的大小可以通过命令行参数-Xss来设置。

除了上述部分,JVM还会使用一些额外的内存空间,如直接内存(DirectMemory)和本地方法栈(Native Method Stack),用于存储一些特殊的数据和执行本地方法。

了解Java的内存使用情况对于定位内存泄漏和优化程序性能非常有帮助。

下面是几个常用的命令,可以用于监控和调整Java程序的内存使用情况:1. jps:该命令用于列出当前运行的Java进程,以及对应的进程ID。

2. jstat:该命令用于监控Java虚拟机的各种运行状态,包括堆的使用情况、类加载数量、垃圾回收情况等。

常用的参数包括-jstat -gcutil <pid>和-jstat-gccapacity <pid>。

JAVA内存泄露、溢出的检查方法、工具介绍

JAVA内存泄露、溢出的检查方法、工具介绍

JAVA内存泄露、溢出的检查⽅法、⼯具介绍问题发现:在我们运⾏的⼀个项⽬上线运营后发现运⾏两天左右就会报内存溢出,只有重启tomcat才能恢复服务,异常信息如下:ng.OutOfMemoryError: GC overhead limit exceededng.OutOfMemoryError: Java heap space原因分析:在此之前必须先介绍⼀下关于jvm的内存控制,JVM即java虚拟机,它运⾏时候占⽤⼀定的内存,其⼤⼩是有限定的,如果程序在运⾏时jvm 占⽤的内存⼤于某个限度,则会产⽣内存溢出,也就是“ng.outofmemoryerror”。

如果jvm内存的没有限度,并且有⽆限⼤的内存,那jvm就永远不会出现内存溢出了。

很明显⽆限的内存是不现实的,但是⼀般情况下我们程序运⾏过程所需要的内存应该是⼀个基础固定的值,如果仅是因为我们的项⽬所需内存超过了jvm设置内存值导致内存溢出,那么我们可以通过增⼤jvm的参数设置来解决内存溢出的问题。

详细处理可参考java jvm的如下参数设置:-Xms -Xmx -Xmn -Xss-Xms: 设置JVM初始内存,此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

-Xmx:设置JVM最⼤可⽤内存。

-Xmn:设置年轻代⼤⼩,整个堆⼤⼩=年轻代⼤⼩+年⽼代⼤⼩+持久代⼤⼩.持久代⼀般固定⼤⼩为64m,所以增⼤年轻代后,将会减⼩年⽼代⼤⼩.此值对系统性能影响较⼤,Sun官⽅推荐配置为整个堆的3/8.-Xss:设置每个线程的堆栈⼤⼩.在相同物理内存下,减⼩这个值能⽣成更多的线程.但是操作系统对⼀个进程内的线程数还是有限制的,不能⽆限⽣成。

在jvm参数调试过程中,发现分配最⼤内存数超过1G后,仍然会产⽣内存溢出的现象,⽽估计其正常分配使⽤的内存应该不会超过1G,那么由此可以基本断定其存在内存泄露现象,也就是⼀些原来分配的不再使⽤的内存不能被java的垃圾回归所回收,导致不断占⽤原分配的内存⽽不释放,导致不断申请更多的内存直到超过内存设置⽽导致内存溢出。

Java内存模型描述及变量运用分析

Java内存模型描述及变量运用分析

Java内存模型描述及变量运用分析Java内存模型(JMM)是一种规范,定义了Java虚拟机如何与计算机内存交互,以及多线程之间如何相互访问共享变量。

JMM负责保证多线程程序的正确性和可见性。

在JMM 中,内存被划分为两个部分:主内存和工作内存。

主内存是所有线程共享的内存区域,而每个线程都有自己的工作内存,因此线程之间不能直接读写主内存中的变量。

Java中的变量包括基本类型、对象引用和对象实例。

它们在内存中的存储方式和访问方式有着很大的不同。

基本类型的变量(如int、float等)直接被存储在工作内存和主内存中。

对象引用变量指向的是对象在堆中的地址,在工作内存中保存的是对象引用的副本,而对象实例则在堆中保存。

Java内存模型由以下规则来保证多线程程序的正确性:1. 原子性:一个操作是原子性的,就是说它要么完全执行完成,要么没有执行。

2. 可见性:如果一个线程修改了一个变量的值,其他线程应该能够立即知道这个变量的变化。

3. 有序性:Java中程序的执行顺序或指令的执行顺序不应该对最终结果产生影响。

4. 线程安全性:当多个线程同时访问一个共享变量时,不会出现数据竞争和状态不一致的情况。

在Java中,我们可以使用synchronized关键字、volatile变量和锁等机制来保证线程安全性和可见性。

关键字synchronized可以用来实现线程之间的同步,保证同一时刻只有一个线程可以访问共享变量。

而volatile变量可以保证每次修订都能够被其他线程看到,并且不会被编译器优化掉。

在实际编程中,我们应该尽可能地避免多线程之间的竞争。

如果必须要共享变量,就应该使用线程安全的数据结构(如线程安全的集合类)等来保证线程安全性。

一般来说,我们应该避免在多个线程之间共享数据,而是应该将数据封装到单独的对象中。

另外,我们还可以使用ThreadLocal类来保证同一个线程内的变量是唯一的。

ThreadLocal类可以为每个线程创建一个独立的变量副本,避免了线程之间的共享问题。

Java内存分析工具jmap

Java内存分析工具jmap

Java内存分析⼯具jmap1.简述 jmap是⼀个多功能的命令,它可以⽣成java程序的dump⽂件,也可以查看堆内对象⽰例的统计信息、查看ClassLoader的信息以及finalizer队列。

2.jmap的⽤法 (1)jmap参数说明 参数说明:option:选项参数。

pid:需要打印配置信息的进程ID。

executable:产⽣核⼼dump的Java可执⾏⽂件。

core:需要打印配置信息的核⼼⽂件。

server-id:可选的唯⼀id,如果相同的远程主机上运⾏了多台调试服务器,⽤此选项参数标识服务器。

remote server IP or hostname:远程调试服务器的IP地址或主机名。

option选项参数说明:no option:查看进程的内存映像信息。

heap:显⽰Java堆详细信息。

histo[:live]:显⽰堆中对象的统计信息。

permstat:打印类加载器信息。

finalizerinfo:显⽰在F-Queue队列等待Finalizer线程执⾏finalizer⽅法的对象。

dump:<dump-options>:⽣成堆转储快照。

F:当-dump没有响应时,使⽤-dump或者-histo参数,在这个模式下,live⼦参数⽆效。

help:打印帮助信息。

J<flag>:指定传递给运⾏jmap的JVM的参数。

(2)no option⽰例 命令:jmap pid 描述:使⽤不带选项参数的jmap打印共享对象映射,将会打印⽬标虚拟机中加载的每个共享对象的起始地址、映射⼤⼩以及共享对象⽂件的路径全称。

这与Solaris的pmap⼯具⽐较相似。

(3)heap⽰例 命令:jmap -heap pid 描述:打印⼀个堆的摘要信息,包括使⽤的GC算法、堆配置信息和各内存区域内存使⽤信息。

C:\Users\Administrator>jmap -heap 1760Attaching to process ID 1760, please wait...Debugger attached successfully.Server compiler detected.JVM version is 24.80-b11using thread-local object allocation. #新⽣代采⽤的是并⾏线程处理⽅式Parallel GC with 4 thread(s) #同步并⾏垃圾回收Heap Configuration: #堆配置情况,也就是JVM参数配置的结果【平常说的tomcat配置JVM参数,就是在配置这些】MinHeapFreeRatio = 0 #最⼩堆使⽤⽐例MaxHeapFreeRatio = 100 #最⼤堆可⽤⽐例MaxHeapSize = 2147483648 (2048.0MB) #最⼤堆空间⼤⼩NewSize = 1310720 (1.25MB) #新⽣代分配⼤⼩MaxNewSize = 536870912 (512.0MB) #最⼤可新⽣代分配⼤⼩OldSize = 5439488 (5.1875MB) #⽼年代⼤⼩NewRatio = 2 #新⽣代⽐例SurvivorRatio = 8 #新⽣代与suvivor的⽐例PermSize = 21757952 (20.75MB) #perm区永久代⼤⼩MaxPermSize = 2147483648 (2048.0MB) #最⼤可分配perm区也就是永久代⼤⼩G1HeapRegionSize = 0 (0.0MB)Heap Usage: #堆使⽤情况【堆内存实际的使⽤情况】PS Young GenerationEden Space: #伊甸区capacity = 413663232 (394.5MB) #伊甸区容量used = 41933104 (39.99052429199219MB) #伊甸区已经使⽤⼤⼩free = 371730128 (354.5094757080078MB) #剩余容量10.137015029655814% used #伊甸区使⽤情况From Space: #survior1区capacity = 58195968 (55.5MB) #survior1区容量used = 0 (0.0MB) #surviror1区已使⽤情况free = 58195968 (55.5MB) #surviror1区剩余容量0.0% used #survior1区使⽤⽐例To Space: #survior2区capacity = 56623104 (54.0MB) #survior2区容量used = 0 (0.0MB) #survior2区已使⽤情况free = 56623104 (54.0MB) #survior2区剩余容量0.0% used #survior2区使⽤⽐例PS Old Generation #⽼年代使⽤情况capacity = 458227712 (437.0MB) #⽼年代容量used = 243170504 (231.90546417236328MB) #⽼年代已使⽤容量free = 215057208 (205.09453582763672MB) #⽼年代剩余容量53.0676119387559% used #⽼年代使⽤⽐例PS Perm Generation #永久代使⽤情况capacity = 176685056 (168.5MB) #perm区容量used = 92300856 (88.02495574951172MB) #perm区已使⽤容量free = 84384200 (80.47504425048828MB) #perm区剩余容量52.240329821668674% used #perm区使⽤⽐例62625 interned Strings occupying 7287440 bytes.View Code(4)histo[:live]⽰例 命令:jmap -histo:live pid 描述:包括每个Java类、对象数量、内存⼤⼩(单位:字节)、完全限定的类名。

JAVA内存分析

JAVA内存分析

java内存分析(2011-12-06 20:16:19)转载▼标签:杂谈Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java在内存分配方面的知识。

一般Java在内存分配时会涉及到以下区域:◆寄存器:我们在程序中无法控制◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中◆堆:存放用new产生的数据◆静态域:存放在对象中用static定义的静态成员◆常量池:存放常量◆非RAM存储:硬盘等永久存储空间Java内存分配中的栈在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配。

当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

Java内存分配中的堆堆内存用来存放由new创建的对象和数组。

在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。

在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。

引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

引用变量就相当于是为数组或者对象起的一个名称。

引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。

而数组和对象本身在堆中分配,即使程序运行到使用new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。

这也是Java 比较占内存的原因。

JVM内存及内存溢出分析

JVM内存及内存溢出分析

JVM内存分析1.组成Java把内存分为栈区(Stack Segment)、堆区(Heap Segment)、静态区(Data Segment)、代码区(Code Segment)四部分。

1.1栈区(Stack Segment)栈区存放函数参数值、局部变量的值等,由编译器自动分配,方法执行结束后系统自动释放。

在方法(代码块)中定义一个变量时,Java在栈中为这个变量分配内存空间,当变量超过作用域后,Java自动释放掉该变量所分配的内存空间。

1.2堆区(Heap Segment)堆区存放(由程序员)以new方式创建的对象和数组,jvm的GC按照某种垃圾收集机制检查对象的引用指向,如果没有,GC负责回收(释放)。

Heap区分为New Generation和Old Generation,1.2.1New Generation●Eden,存放新对象的空间●Survivor Space,残存空间,包括From区和To区●每次GC,将Eden中存活对象Copy到Survivor Space,并清空Eden。

如果在Copy时候,如果Survivor Space已满,则将剩余存活对象Copy到Old Generation●1级及以上GC为部分垃圾回收,仅回收New Generation中垃圾1.2.2Old Generation●当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区●当OLD区空间不够时,JVM会在OLD区进行0级的垃圾收集(完全)●完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现"out of memory错误"1.3代码区存放程序中方法的二进制代码,而且是多个对象共享一个代码空间区域1.3.1Permanent Generation●主要用来放JVM自己的反射对象,比如类对象和方法对象●如何知道Permanent Generation已满,-XX:+PrintGCDetails●手工设置,-XX:MaxNewSize=256m。

java常见的内存资源分析、性能分析工具有哪些?

java常见的内存资源分析、性能分析工具有哪些?
1.VisualVM
VisualVM是一个资源分析工具,一直从JDK 6更新到7,它默认内存和CPU的监视,它可以告诉你哪个类和方法消耗资源,但它不会显示代码流程。
2.JProfiler
JProfiler很容易安装,并且通过向导,你可以选择应用服务器用来运行应用程序。我不得不选择使用JPofiler应用服务器的主目录,以及向导生成的一个单独的启动脚本。然后运行服务器。在监听会话的过程中,它会提供几个选项,它可以记录内存的使用和CPU的使用率。在查看CPU使用率的同时,可以看到执行路径。这让我看到应用程序大部分时间都花在请求上。我们可以将IntelliJ插件安装到IDE上,那么运行JProfiler会更加便利。比如,可以直接帮我启动Tomcat。
我刚开始创建JProbe时遇到点困难。安装并不是直接完成,我需要对它进行配置。它采用了类似JProfiler一样的设置。它会在你的Tomcat目录中生成启动脚本,可以通过脚本启动服务器并监听会话。它的界面包含有按钮和表格,其中可以看到内存的使用,但无法在进程中找到执行路径。 5来自Spring Insight
结 论
如果你有基于Spring的应用程序,那么选择Spring Insight显然是最佳的。它一直是免费的,但你需要部署你的应用在TC Server上。
如果你想监听本地和远程的进程,我会选择JProfiler或YourKit.这两个也可以帮助Spring Insight来监测、找到性能瓶颈。
JProfiler和YourKit已经能满足我的上述要求。JProfiler、YourKit和Spring Insight都可以跟踪应用程序的类和方法的流向。JProfiler和YourKit可以显示内存使用情况。虽然Spring Insight不可以显示内存使用情况,但它可以很好的显示吞吐量的趋势。这三款性能分析工具功能很清楚,不混乱,而且容易使用。最后,他们都有自己的 IDE插件。希望本文能帮助你做出正确的选择。

java oom排查思路

java oom排查思路

java oom排查思路
1、观察内存状况:查看Java虚拟机内存消耗情况,检查内存消耗是否超过常规水位,判断服务器内存是否不足。

2、查看线程状况:查看进程中的所有线程,是否存在持续增多的线程,或者某个线程占用大量的内存和CPU。

3、查看GC日志:查看GC日志,看看是否存在内存抖动,或者内存回收缓慢导致的内存不足。

4、代码调优:查看代码,查看是否存在内存泄露点和频繁创建对象的地方,定位代码是否需要进行优化,以提升Java程序运行效率。

5、调整堆内存大小:在此之前,需要先查看程序运行情况,判断是否需要调整程序的内存设置,如堆大小等。

6、升级JVM:查看Java虚拟机版本,如果版本过老,可能会存在漏洞和BUG,可以考虑升级至最新版本。

查看java内存情况的几个常用命令

查看java内存情况的几个常用命令

查看java内存情况的⼏个常⽤命令java 命令简单查看jvm内存使⽤状况jinfo:可以输出并修改运⾏时的java 进程的opts。

jps:与unix上的ps类似,⽤来显⽰本地的java进程,可以查看本地运⾏着⼏个java程序,并显⽰他们的进程号。

jstat:⼀个极强的监视VM内存⼯具。

可以⽤来监视VM内存内的各种堆和⾮堆的⼤⼩及其内存使⽤量。

jmap:打印出某个java进程(使⽤pid)内存内的所有'对象'的情况(如:产⽣那些对象,及其数量)。

1、jinfojinfo:的⽤处⽐较简单,就是能输出并修改运⾏时的java进程的运⾏参数。

⽤法是jinfo -opt pid 如:查看52606的MaxPerm⼤⼩可以⽤ jinfo -flag MaxPermSize 52606。

2、jps显⽰当前所有java进程pid的命令,我们可以通过这个命令来查看到底启动了⼏个java进程(因为每⼀个java程序都会独占⼀个java虚拟机实例),不过jps有个缺点是只能显⽰当前⽤户的进程id,要显⽰其他⽤户的还只能⽤linux的ps命令。

执⾏jps命令,会列出所有正在运⾏的java进程,其中jps命令也是⼀个java程序,前⾯的数字就是对应的进程id,这个id的作⽤⾮常⼤,后⾯会有相关介绍。

jps -help:jps -l :输出应⽤程序main.class的完整package名或者应⽤程序jar⽂件完整路径名jps -v:输出传递给JVM的参数jps失效我们在定位问题过程会遇到这样⼀种情况,⽤jps查看不到进程id,⽤ps -ef | grep java却能看到启动的java进程。

要解释这种现象,先来了解下jps的实现机制:java程序启动后,会在⽬录/tmp/hsperfdata_{userName}/下⽣成⼏个⽂件,⽂件名就是java进程的pid,因此jps列出进程id就是把这个⽬录下的⽂件名列⼀下⽽已,⾄于系统参数,则是读取⽂件中的内容。

java内存泄漏排查思路

java内存泄漏排查思路

java内存泄漏排查思路Java内存泄漏是指程序在运行过程中,无法回收不再使用的内存空间,导致内存占用不断增加,最终耗尽系统内存资源的问题。

内存泄漏会导致程序性能下降、系统崩溃等严重后果,因此及时排查和解决内存泄漏问题是非常重要的。

下面将介绍一些Java内存泄漏排查的思路和方法,帮助开发人员更好地定位和解决内存泄漏问题。

1. 使用内存分析工具:内存分析工具是排查内存泄漏问题的重要利器,常用的工具有Eclipse Memory Analyzer(MAT)、VisualVM、YourKit等。

这些工具可以帮助开发人员分析堆内存中的对象,查看对象的引用关系,定位到可能存在内存泄漏的对象。

2. 分析GC日志:GC日志记录了垃圾回收的过程,可以通过分析GC日志来判断是否存在内存泄漏。

可以使用参数-Xloggc:file将GC日志输出到文件中,然后使用工具(如GCViewer)来分析GC日志,查看堆内存的变化情况和对象的回收情况。

3. 内存泄漏排查工具:除了内存分析工具外,还有一些专门用于排查内存泄漏的工具,如LeakCanary、XRebel等。

这些工具可以自动检测和定位内存泄漏问题,提供可视化的结果展示,简化了排查的过程。

4. 注意弱引用和软引用:Java提供了弱引用(WeakReference)和软引用(SoftReference)来解决内存泄漏的问题。

使用弱引用和软引用可以避免对象被强引用所持有,从而被垃圾回收器回收。

开发人员在编写代码时,应该注意对象引用的强度,避免造成内存泄漏。

5. 关注线程和线程池:线程和线程池是常见的内存泄漏源,因为线程和线程池在使用完毕后需要显式地关闭。

如果没有正确地关闭线程或线程池,会导致线程对象无法被垃圾回收,从而造成内存泄漏。

要注意在使用完毕后及时关闭线程和线程池。

6. 避免静态引用:静态变量会一直存在于内存中,如果静态变量引用了其他对象,那么这些对象也无法被垃圾回收。

Jvm内存分配概述与相关配置详解

Jvm内存分配概述与相关配置详解

Jvm内存分配概述与相关配置详解Java虚拟机运行时数据区程序计数器是一块较小的内存空间,可以看成是当前线程所执行的字节码的行数指示器。

如果线程正在执行一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行一个native方法,这个计数器就为空(Undefined)。

此内存区域是唯一一个Java 虚拟机规范中没有规定任何OurOfMemberError的区域。

Java虚拟机栈,位虚拟机执行Java方法服务,线程私有的,生命周期与线程相同。

在Java 虚拟机规范中,这个区域规定了两种异常:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverFlowError异常;如果虚拟机栈可以动态扩展,在扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

本地方法栈为虚拟机使用到的Native方法服务,与虚拟机栈一样也会抛出StackOverFlowError和OutOfMemoryError异常。

Java堆是虚拟机管理的内存中最大的一块,它唯一的目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

它不需要连续的内存可以选择固定的大小或者可扩展。

它也是垃圾收集器管理的主要区域(GC堆)。

通过-Xmx和-Xms可以动态扩展堆大小。

堆无法再扩展时就会抛出OutOfMemoryError异常。

方法区也是哥哥线程共享的内存区域,用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译期编译后的代码等数据。

Java虚拟机规范中描述为堆的唯一逻辑部分,对方法区的限制非常宽松。

它不需要连续的内存可以选择固定的大小或者可扩展,还可以选择不实现垃圾收集。

无法满足内存分配需求时抛出OutOfMemoryError异常。

堆大小设置:JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。

Java程序内存分析:使用mat工具分析内存占用

Java程序内存分析:使用mat工具分析内存占用

Java程序内存分析:使⽤mat⼯具分析内存占⽤------------------------------------------------------------------------------------------------------------------------------------------------------------------在⼯作中可能会遇到内存溢出这种灾难性的问题,那么程序肯定是存在问题,找出问题⾄关重要,上⼀篇⽂章讲了jmap命令的使⽤⽅法,当然⽤jmap导出的⽂件我们也看不懂啊,那就交给memory analyzer(mat)这个⼯具,让他帮助我们来观察程序的内存分布情况吧。

造成OutOfMemoryError原因⼀般有2种:1、内存泄露,对象已经死了,⽆法通过垃圾收集器进⾏⾃动回收,通过找出泄露的代码位置和原因,才好确定解决⽅案;2、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不⾜,检查堆设置⼤⼩(-Xmx与-Xms),检查代码是否存在对象⽣命周期太长、持有状态时间过长的情况。

1. ⽤jmap⽣成堆信息这样在E盘的jmap⽂件夹⾥会有⼀个map.bin的堆信息⽂件2. 将堆信息导⼊到mat中分析3. ⽣成分析报告mat可以为我们⽣成多个报告:下⾯来看看⽣成的这些数据对我们有什么帮助从上图可以看到它的⼤部分功能,在饼图上,你会发现转储的⼤⼩和数量的类,对象和类加载器。

正确的下⾯,饼图给出了⼀个印象最⼤的对象转储。

移动你的⿏标⼀⽚看到对象中的对象的细节检查在左边。

下⾯的Action标签中:Histogram可以列出内存中的对象,对象的个数以及⼤⼩。

Dominator Tree可以列出那个线程,以及线程下⾯的那些对象占⽤的空间。

Top consumers通过图形列出最⼤的object。

Leak Suspects通过MA⾃动分析泄漏的原因。

Java内存模型描述及变量运用分析

Java内存模型描述及变量运用分析

Java内存模型描述及变量运用分析Java内存模型是Java程序员必须了解的重要概念之一。

它描述了Java虚拟机在何时、如何创建、操作和销毁对象,以及如何保证多线程程序的正确性。

Java内存模型主要包括共享内存、Java线程模型以及Java内存模型规范。

共享内存是指多个线程可以同时访问同一个内存地址。

在共享内存模型中,多个线程可以同时访问相同的内存地址,这样就需要考虑内存地址的正确性和一致性问题。

Java中解决这种问题的方式是使用同步机制,如synchronized关键字和volatile关键字。

Java线程模型是由Java虚拟机规定的,用于协调和管理多个线程的能力。

它是支持并发的基础,包括线程的创建、调用、休眠、唤醒、销毁等操作。

Java内存模型规范定义了Java虚拟机如何处理内存。

在Java内存模型中,内存被分为两个区域:堆和栈。

堆包含了所有对象,栈包含了线程的栈帧和局部变量。

Java虚拟机还使用垃圾回收器来管理内存,回收无用对象以释放内存。

变量是程序中存储数据的基本单元。

在Java中,变量可以是成员变量、局部变量或静态变量。

成员变量和静态变量都会在堆中创建,而局部变量会在栈中创建。

变量也需要考虑并发访问的问题,需要使用同步机制来保证数据的正确性和一致性。

例如,如果多个线程需要同时访问一个成员变量,必须使用synchronized关键字来保证数据的正确性。

如果多个线程需要同时访问一个静态变量,可以使用volatile关键字来保证数据的一致性。

总之,Java内存模型描述了Java虚拟机如何处理内存,保证多线程程序的正确性。

变量是程序中存储数据的基本单元,需要使用同步机制来保证数据的正确性和一致性。

Java内存管理原理

Java内存管理原理

Java内存管理原理Java内存怎么划分?经常有人把Java内存区分为堆内存(Heap)和栈内存(Stack),这种分法比拟粗糙,Java内存区域的划分实际上远比这复杂。

这种划分方式的流行只能说明大多数程序员最关注的、与对象内存分配关系最密切的内存区域是这两块。

其中所指的“堆”是为Java堆,所指的“栈”是为虚拟机栈或者说是虚拟机栈中局部变量表局部。

Java虚拟机所管理的内存将会包括以下几个运行时数据区域,如下列图所示:程序计数器是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。

在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等根底功能都需要依赖这个计数器完成。

由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。

因此,为了线程切换后能恢复到正确的执行位置,独立存储,我们称这类区域为“线程私有”的内存。

如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值为空(undefined)。

此内存区域是唯一一个在Java虚拟机标准中没有规定任何OutOfMemoryError情况的区域。

与程序计数器一样,Java虚拟机栈也是线程私有的,生命周期与线程相同。

虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创立一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

每一个方法调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

局部变量表存放了编译期可知的各种根本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。

Java进程占用内存过高,排查解决方法

Java进程占用内存过高,排查解决方法

Java进程占⽤内存过⾼,排查解决⽅法最近收到邮件报警,说内存使作率达到84%。

如下图:解决⽅法:A:可能是代码原因导致的问题:1、使⽤命令:top 查看当前进程的状态2、从上图可以看到PID:916的java进程占⽤内存较⼤。

定位线程问题(通过命令查看PID 为25894 进程的线程情况),命令:# ps p 916 -L -o pcpu,pmem,pid,tid,time,tname,cmd由此可以看到这PID:916的进程产⽣了很多线程。

接下来就可以通过jstack查看内存使⽤的堆栈。

3、查看内存使⽤的堆栈:在这⾥我们挑选了TID=934的线程进⾏分析,⾸先需要将934这个id转换为16进制。

需输⼊如下命令,printf "%x\n" 97314、将PID为916的堆栈信息打印到jstack.log中,命令:jstack -l 916 > jstack.log5、查看堆栈信息⽂件,命令:vim jstack.log在进⾏搜索TID为2603的相关信息。

如图:6、分析可以看到这个线程状态为:RUNNABLE。

是正在运⾏状态的另外其它的⼤部分线程状态为:WAITING。

通过查看⽂件分析看到⼤量 Java Thread State。

说明它在等待另⼀个条件的发⽣,来把⾃⼰唤醒,或者⼲脆它是调⽤了 sleep(N)。

此时线程状态⼤致为以下⼏种:ng.Thread.State: WAITING (parking):⼀直等那个条件发⽣;ng.Thread.State: TIMED_WAITING (parking或sleeping):定时的,那个条件不到来,也将定时唤醒⾃⼰。

7.代码优化:将⽂件发送给开发。

优化下线程B:可能是其他原因导致的问题:1、使⽤ps命令:ps -ef | grep java | grep -v grep查看当前java进程列表root 83410 May13 ? 00:30:09 /usr/lib/jvm/java/bin/java -Djava.util.logging.config.file=/data/apache-tomcat-9.0.13/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKey root 129413 May13 ? 14:41:25 /usr/lib/jvm/java/bin/java -Djava.util.logging.config.file=/data/apache-tomcat-9.0.13/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKe root 208510 Mar05 ? 01:57:08 /usr/lib/jvm/java/bin/java -Djava.util.logging.config.file=/data/apache-tomcat-9.0.13/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKey root 1280810 Mar08 ? 01:16:03 /usr/lib/jvm/java/bin/java -Djava.util.logging.config.file=/data/apache-tomcat-9.0.13/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKe root 1939210 May09 ? 00:36:19 /usr/lib/jvm/java/bin/java -Djava.util.logging.config.file=/data/apache-tomcat-9.0.13/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKe root 1983811 May09 ? 05:32:17 /usr/lib/jvm/java/bin/java -Djava.util.logging.config.file=/data/apache-tomcat-9.0.13/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKe root 2154310 May27 ? 00:22:03 /usr/lib/jvm/java/bin/java -Djava.util.logging.config.file=/data/apache-tomcat-9.0.13/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKe root 2275015 May27 ? 02:28:41 /usr/lib/jvm/java/bin/java -Djava.util.logging.config.file=/data/apache-tomcat-9.0.13/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKe 由上图所⽰,可以看到java进程是Tomcat的启动进程,开启多个Tomcat启动进程,并且是同⼀个端⼝。

java内存管理详细介绍

java内存管理详细介绍

java内存管理详细介绍(本⽂引⽤:/doc/e73e0fafdd3383c4bb4cd25b.html /topic/802573;/doc/e73e0fafdd3383c4bb4cd25b.html /topic/802638;)Java与C++之间有⼀堵由内存动态分配和垃圾收集技术所围成的⾼墙,墙外⾯的⼈想进去,墙⾥⾯的⼈却想出来。

概述:对于从事C、C++程序开发的开发⼈员来说,在内存管理领域,他们即是拥有最⾼权⼒的皇帝⼜是执⾏最基础⼯作的劳动⼈民——拥有每⼀个对象的“所有权”,⼜担负着每⼀个对象⽣命开始到终结的维护责任。

对于Java程序员来说,不需要在为每⼀个new操作去写配对的delete/free,不容易出现内容泄漏和内存溢出错误,看起来由JVM管理内存⼀切都很美好。

不过,也正是因为Java程序员把内存控制的权⼒交给了JVM,⼀旦出现泄漏和溢出,如果不了解JVM是怎样使⽤内存的,那排查错误将会是⼀件⾮常困难的事情。

VM运⾏时数据区域JVM执⾏Java程序的过程中,会使⽤到各种数据区域,这些区域有各⾃的⽤途、创建和销毁时间。

根据《Java虚拟机规范(第⼆版)》(下⽂称VM Spec)的规定,JVM包括下列⼏个运⾏时数据区域:1.程序计数器(Program Counter Register):每⼀个Java线程都有⼀个程序计数器来⽤于保存程序执⾏到当前⽅法的哪⼀个指令,对于⾮Native⽅法,这个区域记录的是正在执⾏的VM原语的地址,如果正在执⾏的是Natvie⽅法,这个区域则为空(undefined)。

此内存区域是唯⼀⼀个在VM Spec 中没有规定任何OutOfMemoryError情况的区域。

2.Java虚拟机栈(Java Virtual Machine Stacks)与程序计数器⼀样,VM栈的⽣命周期也是与线程相同。

VM栈描述的是Java ⽅法调⽤的内存模型:每个⽅法被执⾏的时候,都会同时创建⼀个帧(Frame)⽤于存储本地变量表、操作栈、动态链接、⽅法出⼊⼝等信息。

Java内存区域的使用详解

Java内存区域的使用详解

Java内存区域的使用详解
Java内存划分:
在Java内存分配中,java将内存分为:方法区,堆,虚拟机栈,本地方法栈,程序计数器。

其中方法区和堆对于所有线程共享,而虚拟机栈和本地方法栈还有程序计数器对于线程隔离的。

每个区域都有各自的创建和销毁时间。

程序计数器:
作用是当前线程所执行的字节吗的行号指示器。

Java的多线程是通过线程轮流切换并分配处理器执行时间方式来实现的。

因此,每个线程为了能在切换后能恢复到正确的位置,每个线程需要*的程序计数器。

Java虚拟机栈:
每个放在被执行的时候都会同时创建一个栈帧用于存储局部变量表,*作数栈,动态链接,方法出口等信息。

虚拟内存栈就是我们经常讲的“栈”。

其中局部变量表所需内存是在编译期完成分配。

本地方法栈:
与虚拟机栈类似,区别在于虚拟机栈为虚拟机执行Java方法服务,而本地方法栈为虚拟机使用Native方法服务。

Java堆:
被所有程序共享,并且在虚拟机启动时创建。

此内存区域作用是存放对象实例。

根据Java虚拟机规定,Java堆可以处于物理上不连续的内存空间,只要逻辑上连续即可。

方法区:
与堆相同,在各个线程间共享。

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

运行时常量池:
是方法区的一部分。

作用是存储编译期生成的各种字面量和符号引用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

JA V A内存分析指引2010-071 环境说明根据一般项目部署情况,生产环境以WebSphere5和WebSphere6为主,本文中所涉及环境变量也主要采用WebSphere的相关环境变量。

WebSphere5安装目录(默认):Windows:C:\Program Files\WebSphere\AppServerAIX:/usr/WebSphere/ AppServerWebSphere5日志路径Windows:C:\Program Files\WebSphere\AppServer\logs\server1AIX: /usr/WebSphere/ AppServer/logs/server1WebSphere6安装目录(默认):Windows:C:\Program Files\IBM\WebSphere\AppServerAIX:/usr/IBM/WebSphere/AppServerWebSphere6日志路径:Windows:C:\Program Files\IBM\WebSphere\AppServer\profiles\AppSrv01\logs\server1AIX: /usr/IBM/WebSphere/AppServer/profiles/AppSrv01/logs/server12 内存溢出原理内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。

为了解决Java中内存溢出问题,我们首先必须了解Java是如何管理内存的。

Java的内存管理就是对象的分配和释放问题。

在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(Garbage Collection,GC)完成的。

Java的内存垃圾回收机制是从程序的主要运行对象开始检查引用链,当遍历一遍后发现没有被引用的孤立对象就作为垃圾回收。

GC为了能够正确释放对象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。

监视对象状态是为了更加准确地、及时地释放对象,而释放对象的根本原则就是该对象不再被引用。

在Java中,这些无用的对象都由GC负责回收,因此程序员不需要考虑这部分的内存泄露。

虽然,我们有几个函数可以访问GC,例如运行GC的函数System.gc(),但是根据Java 语言规范定义,该函数不保证JVM的垃圾收集器一定会执行。

因为不同的JVM实现者可能使用不同的算法管理GC。

同时JVM调用GC的策略也有很多种,有的是内存使用到达一定程度时,GC才开始工作,也有定时执行的,有的是平缓执行GC,有的是中断式执行GC。

若GC连续回收不能解决内存堆不足的问题时,就会报out of memory 错误。

PS:显示调用System.GC() 只能建议JVM 需要在内存中对垃圾对象进行回收,不能马上对内存进行回收。

需慎用System.GC(),一个是并不能解决内存资源耗空的局面,另外频繁调用也会增加GC对内存的消耗。

3 内存溢出现象在WebSphere的日志路径下的SystemOut.log日志文件中会出现如下异常信息,系统的可用内存和性能持续下降,最终导致应用服务器系统down掉,不能响应任何请求。

当出现内存溢出时,在IBM WebSphere平台,如果在性能诊断顾问程序配置里面选中了"启用自动堆转储收,在WebSphere的安装目录下(WebSphere6在%安装目录%\profiles\ AppSrv01下)将会生成javacore*、heapdump*之类的文件。

其中,javacore文件记录cpu线程相关信息,heapdump文件记录内存使用信息。

4 内存溢出原因内存溢出主要有以下四个方面的原因:1)内存中加载的数据量过于庞大。

案例一:在我们的项目中很多都用到了Excel导出功能,当一次导出的数据量过大时可能出现内存溢出的情况。

案例二:在查询数据时,如果查询的数据量过于庞大,也可能会导致内存溢出的情况。

一般可以考虑通过分页机制来减少每次数据加载量。

2)在代码中出现死循环和死递归3)JVM的内存值设置过小。

生产环境一般建议初始值512M,最大值1024M。

最好不要超过1.5G4)集合类和数组的使用不规范,存在对象的引用未消除,导致JVM不能回收或内存泄露的情况。

5 内存溢出分析与诊断内存分析与诊断一般步骤:检查JVM参数配置->检查系统日志->收集内存溢出信息->代码走查->内存工具分析5.1检查JVM参数配置检查WAS配置的JVM启动内存参数,确认该参数是否配置合理。

在一些项目中由于本身的业务逻辑复杂,需要较大的内存开销,而内存参数设置过小,导致内存溢。

WAS配置方法:应用程序服务器> server1 > 进程定义> Java 虚拟机,将最大堆大小(默认为256M)修改为一个合理的值,一般设为1024M,最好不要超过1.5G。

PS:在配置该参数时不能盲目的配置,如果配置过小,JVM的GC过于频繁,开销过大导致系统运行缓慢,内存溢出的概率会较大。

如果配置过大,JVM在GC的时候,耗费时间过长。

也会影响系统的性能和使用效果。

5.2检查错误日志检查WebSphere日志路径下的SystemOut.log和SystemErr.log文件。

查看在出现“OutOfMemory”错误前是否有其它异常或错误。

对于前面所描述程序上的一些死循环、死递归的BUG可以很快根据抛出的异常信息进行定位。

例如在EHR的动态报表系统,一个构造指标树的程序中,由于没有控制指标选择,在树的节点上出现了相同的ID的同一个指标,因致死递归导致内存溢出使系统宕机。

通过在指标选择时加以控制,不让添加重复指标,解决了内存溢出的错误。

查看日志对于分析内存溢出是非常重要的,通过仔细查看日志,分析内存溢出前做过哪些操作,可以大致定位有问题的模块。

5.3收集内存溢出信息WAS中自带了一些内存泄漏的探测工具,启动这些工具WAS就可以对内存溢出发生警报。

例如:1)性能诊断顾问,可以将输出信息显示在WebSphere的管理控制台,并记录在WebSphere应用服务器的SystemOut.log日志文件里面。

2)启用JVMTI,可以使用PMI 定制选项来启用所选统计信息以收集特定数据。

在WebSphere应用服务器的日志目录下,native_stderr.log文件就是内存回收分析文件。

PMAT工具解析JAVA SDK的详细内存回收(GC)日志,并提供统计信息,图表,分析并推荐Java堆配置。

PMAT提供了丰富的图形界面来显示Java堆的使用状况,从而更轻松地判断是否有内存问题发生。

3)启用自动堆转储收集,可以自动在WebSphere profile所在的路径下生成heapdump 文件。

可以使用IBM HeapAnalyzer、MDD4J等内存泄露分析工具对heapdump文件进行分析。

显示主内存转储中Java 堆占用量的主要组成部分的拥有关系上下文图,根据对对象引用图执行的深度优先遍历,用树形视图显示主内存转储的所有内容。

这是我们比较常用的分析内存溢出的方法。

5.4代码走查对代码进行走查和分析,找出可能发生内存溢出的位置。

重点排查以下几点:1)检查代码中是否有死循环或递归调用2)检查是否有大循环重复产生新对象实体。

3)检查对数据库查询中,是否有一次获得全部数据的查询。

一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。

这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。

对于数据库查询建议尽量采用分页的方式查询。

4)检查List、MAP等集合对象是否有使用完后,未清除的问题。

List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

5.5内存工具分析使用内存查看工具动态查看内存使用情况。

监测Java程序运行时所有对象的申请、释放等动作,将内存管理的所有信息进行统计、分析、可视化。

根据这些信息判断程序是否有内存泄漏问题。

一般来说,一个正常的系统在其启动完成后其内存的占用量是基本稳定的,而不应该是无限制的增长的。

对内存快照中对象的使用与引用等信息进行比对与分析,可以找出是哪个类的对象在泄漏。

6 内存分析工具6.1内存监控工具Jprobe通过Jprobe的JProbe Memory Debugger的功能能够快速查找Java代码的内存泄露和对象循环。

JProbe Memory Debugger内置的图形化实时内存使用和对象视图,有助于我们来理解应用的内存使用,设法减少内存消耗以提高应用性能。

主要功能如下:1)识别内存泄漏:通过易用的两步分析,跟踪运行时的内存增长;2)Memory Instance Calculator:计算内存泄露量;3)智能化内存分析:通过Leak Doctor发现可能的内存泄露源;4)Aggregate Memory Footprint:理解对象创建的实际开销;5)Reference Graph 和Instance Detail:跟踪内存使用和对象引用;6)垃圾回收分析:检测过多的短期对象和垃圾收集详情;7)Snapshot 比对:确定代码改变对内存使用的影响PS:最新版的8.1对WAS5不支持,如需要监控WAS5的内存使用情况,需要低版本如Jprobe5破解版下载地址://Crack/2009/05/JProbe.Suite.v8.1.0.Cracked-FALLEN.rar Jprobe使用简介:1)启动Jprobe,配置需要监控的web容器,以Tomcat为例说明。

Welcome界面中点击Create/Edit Setting2)选择Apache,点击Add按钮,根据提示,点击next,选择Tomcat安装目录,启动脚本,Analysis Type选择Memory,保存配置。

3)选择配置好的web容器名,点击Run,启动需要监控的Tomcat。

4)Welcome界面,点击,可看到Tomcat初始化内存使用情况。

记录当前内存的总体使用情况,点击图表,生成一个当前的快照(Takea Snapshot)5)快照分析,双击左边树结构上生成的snapshot,可看到当前加载的类的内存使用情况,右键可导出结果到CSV文件6)执行需要监控的程序,再生成一个snapshot,记录snapshot分析结果,跟初始snapshot 对比分析可看到新加载了哪些类,每个类的内存使用情况。

7)点击图标,手动GC。

手动GC后再记录一个snapshot,记录snapshot分析结果,对比GC后snapshot与程序执行后的snapshot中各个类的内存使用情况,可检查看哪些类的内存使用在GC后没有回收。

相关文档
最新文档