此篇文章用于查内存泄漏和FullGC
因为在Linux环境,用jdk自带的jmap工具(Linux/Unix环境特有的),可以对进程中的内存对象监视,然后就运行命令
jmap -histo [pid],找内存中的对象数目变化。
jvm中对象内存占用情况(jmap -histo pid | head -n8, 因为内容太多, 因此需要head一下)
导出整个JVM中的内存信息
通过以上方法能查看到JVM中对象内存的占用情况,但很多时候还要知道这个对象到底是谁创建的。例如上面显示出来的[C,只知道它占用了那么多的空 间,但不知道是什么对象创建出的[C,于是jmap提供了导出整个jvm中的内存信息的支持。基于一些jvm内存的分析工具,例如sun JDK 6中的jhat、Eclipse Memory Analyzer,可以分析jvm中内存的详细信息,例如[C是哪些对象创建的。
----------------------------------------------------
执行如下命令即可导出整个jvm中的内存信息:
- jmap -dump:format=b,file=文件名 [pid]
- 在用jhat -J-Xmx1024M [file] 这里的file就是步骤1中的文件名,
- 执行后等待console中输出Started HTTP server on port 7000,看到后就可以通过浏览器访问http://ip:7000/了,此页面默认为按package分类显示系统中所有的对象实例。在页面的最下端有Other Queries导航,其中有显示jvm中对象实例个数的链接、有显示jvm中对象大小的链接等,点击显示jvm中对象大小的链接
-------------------------------------------------------
jmap -heap [pid] 在linux上执行改命令,就可查看整个JVM中各个代的内存状况
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 1610612736 (1536.0MB)
NewSize = 524288000 (500.0MB)
MaxNewSize = 524288000 (500.0MB)
OldSize = 4194304 (4.0MB)
NewRatio = 8
SurvivorRatio = 8
PermSize = 100663296 (96.0MB)
MaxPermSize = 268435456 (256.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 430702592 (410.75MB)
used = 324439936 (309.4100341796875MB)
free = 106262656 (101.3399658203125MB)
75.32806675098904% used
From Space:
capacity = 46333952 (44.1875MB)
used = 13016424 (12.413429260253906MB)
free = 33317528 (31.774070739746094MB)
28.092626331550566% used
To Space:
capacity = 46792704 (44.625MB)
used = 0 (0.0MB)
free = 46792704 (44.625MB)
0.0% used
PS Old Generation
capacity = 1086324736 (1036.0MB)
used = 945707880 (901.8973159790039MB)
free = 140616856 (134.1026840209961MB)
87.05572548059884% used
PS Perm Generation
capacity = 100663296 (96.0MB)
used = 46349592 (44.202415466308594MB)
free = 54313704 (51.797584533691406MB)
46.044182777404785% used
如果PS Old Generation或者PS Perm Generation被填满,就会导致fullGC,进而导致CPU占用率大幅度提高
--------------------------------
并发回收 CMS收集器 UseConcMarkSweepGC
适用情况:“对响应时间有高要求”,多CPU、对应用响应时间有较高要求的中、大型应用。举例:Web服务器/应用服务器、电信交换、集成开发环境。
并行回收 UseParallelGC
--适用情况:“对吞吐量有高要求”,多CPU、对应用响应时间无要求的中、大型应用。举例:后台处理、科学计算。
--缺点:垃圾收集过程中应用响应时间可能加长
最大垃圾回收暂停:指定垃圾回收时的最长暂停时间,通过-XX:MaxGCPauseMillis=<N>指定。<N>为毫秒.如果指定了此值的话,堆大小和垃圾回收相关参数会进行调整以达到指定值。设定此值可能会减少应用的吞吐量。
吞吐量:吞吐量为垃圾回收时间与非垃圾回收时间的比值,通过-XX:GCTimeRatio=<N>来设定,公式为1/(1+N)。例如,-XX:GCTimeRatio=19时,表示5%的时间用于垃圾回收。默认情况为99,即1%的时间用于垃圾回收。
引用一个网友实例:
猜想:在HeapSpace逼近临界值的时候,分配小块内存(譬如创建一个对象,如果是分配大块内存,实际上JVM直接就报OutOfMemory 了),JVM发现内存不足,会尝试去FullGC出空闲内存,每次还真能挤出一点点,但很快又得重新FullGC,我们知道,实际上FullGC是非常消 耗CPU的操作。但为啥不报OutOfMemory呢?因为每次总能够释放出一点点内存,因此竟然就这么维持下去了。这里非常郁闷,JVM直接报 OutOfMemory还好过一点,至少直接知道原因。
JVM一般启动参数有一个GCTimeRatio参数,表示目标吞吐量,JVM会自动调整各内存区大小去达到该吞吐量值,如果吞吐量低于某个值,是会自动 OutOfMemory,目前该值默认是1,表示GC时间占总时间不超过1%,但目前来看,要通过这种方式去让JVM直接报告OutOfMemory而不 是持续维持高CPU看起来是不行的。
已经可以定位到是内存达到临界值的问题,接下来问题就简单了,dump出HeapSpace空间,使用Eclipse Memory Analyzer分析一下,原因一目了然,有点讶异,竟然是BlackStar的detail工作模式导致的,这里是因为使用的时候策略没有调整好,调整 detail策略,重新启动JVM,问题解决,当然这里BlackStar的detail工作模式的自我保护方式也不好,实际上当发现使用内存过多的时 候,应该调整自动放弃。
----------------------------------------------------------------
JStat用于GC分析的参数有:-gc、-gccapacity、-gccause、-gcnew、-gcnewcapacity、 -gcold、-gcoldcapacity、-gcpermcapacity、-gcutil。常用的为-gcutil。通过-gcutil可按一定频 率查看jvm中各代的空间的占用情况、minor GC的次数、消耗的时间、full GC的次数及消耗的时间的统计,执行jstat -gcutil [pid] [interval],另外可以指定更新频率,如-h5 1s:每一秒更新一次,并每隔5条加上header显示,比如jstat -gcutil -h5 28525 1s,表示每隔一秒更新一次,并每隔5条加上header显示
可看到类似如下的输出信息:
S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 74.24 96.73 73.43 46.05 17808 382.335 208 315.197 697.533 45.37 0.00 28.12 74.97 46.05 17809 382.370 208 315.197 697.568
其中S0、S1就是Survivor空间的使用率,E表示Eden空间的使用率,O表示旧生代空间的使用率,P表示持久代的使用率,YGC表示 minor GC的执行次数,YGCT表示minor GC执行消耗的时间,FGC表示Full GC的执行次数,FGCT表示Full GC执行消耗的时间,GCT表示Minor GC+Full GC执行消耗的时间。
观察了一下外网数据,每隔两分钟会执行一次minor GC,也就是说Eden空间每隔两分钟就会被充满,然后会填充S0或者S1,填充次序为轮换执行,也就是这次为S0,下次必为S1,
FGC的平均时间为1S左右,minor GC的平均时间为16ms,也就是一个晶振时间,平均一天一次FGC,710次minor GC
对TJ06-盛大3区 gameserver采样
S0:Heap上的 Survivor space 0 段已使用空间的百分比
S1:Heap上的 Survivor space 1 段已使用空间的百分比
E: Heap上的 Eden space 段已使用空间的百分比
O: Heap上的 Old space 段已使用空间的百分比
P: Perm space 已使用空间的百分比
YGC:从程序启动到采样时发生Young GC的次数
YGCT:Young GC所用的时间(单位秒)
FGC:从程序启动到采样时发生Full GC的次数
FGCT:Full GC所用的时间(单位秒)
GCT:用于垃圾回收的总时间(单位秒)
jstat -gccapacity <jpid>:JVM各区的剩余状态
------------------------------------------------------
jps 目前正在运行中的java进程
-----------------------------------------------------
jstack
jstack -l <jpid>:显示线程阻塞/死锁情况
了解 Java 进程及其对应的执行线程内部发生的情况是一种常见的诊断挑战。例如,当一个应用程序突然停止进程时,很明显出现了资源耗尽,但是仅通过查看代码无法明确知道何处出现资源耗尽,且为什么会发生。
jstack 是一个可以返回在应用程序上运行的各种各样线程的一个完整转储的实用程序,您可以使用它查明问题。
采用期望进程的 VMID 运行 jstack 会产生一个堆转储。就这一点而言,jstack 与在控制台窗口内按 Ctrl-Break 键起同样的作用,在控制台窗口中,Java 进程正在运行或调用 VM 内每个 Thread 对象上的 Thread.getAllStackTraces() 或 Thread.dumpStack()。jstack 调用也转储关于在 VM 内运行的非 Java 线程的信息,这些线程作为 Thread 对象并不总是可用的。
jstack 的 -l 参数提供了一个较长的转储,包括关于每个 Java 线程持有锁的更多详细信息,因此发现(和 squash)死锁或可伸缩性 bug 是极其重要的。
----------------------------------------------------
JVM内存状况查看方法和分析工具
Eclipse Memory Analyzer
Eclipse Memory Analyzer是Eclipse提供的一个用于分析jvm堆dump文件的插件,借助这个插件可查看对象的内存占用状况、引用关系、分析内存泄露等。
Eclipse Memory Analyzer(MAT)的网站为:http://www.eclipse.org/mat/,在eclipse中可以直接远程安装此插件。不过由于此插件在分析堆dump文件时比较耗内存,因此在分析前最好先将eclipse的jvm的内存设置大一点,MAT分析dump文件后的对象占用内存及引用关系如图3.23所示。
相对而言MAT功能比jhat强大很多,分析的速度也快一些,因此,如果要分析jvm堆dumap文件,首选推荐的是MAT。
在进行JVM内存状况分析时,通常要关注的主要有GC的趋势、内存的具体消耗状况。
GC趋势对于可图形界面连到需查看GC状况的机器的情况而言,VisualVM是常用的选择;对于不能采用图形界面方式的,输出GC日志 及采用jstat命令直接分析是常用的选择。
在查找内存是程序中的什么对象占用时,需要分析内存的具体消耗状况,对于有图形界面可用的情况,VisualVM是常用的选择;对于不能采用图形界面方式的,可通过jmap dump生成文件后,再通过MAT进行分析是常用的选择。
参考文献:
CMS gc实践总结(纠正并发线程数)
记一次Java GC调整经历
最后附上JVM参数调优的案例,其中批注一下-server的参数使用
.-server
-client
虚拟机服务器模式/客户机模式,使用server模式可以提高性能,启动比client模式慢,长期运行则比client模式快。当该参数不指定 时,虚拟机启动检测主机是否为服务器,如果是则以server模式启动,否则以client模式启动,J2SE5.0检测的根据是至少2个CPU和最低 2GB内存
jstat pid not found
今天在用jstat命令的时候,遇到pid not found的问题,然,自己确定pid输入是正确存在的,但为什么呢?
原来运维那边每隔一个月,一般在月底都会去清空一下tmp目录下的文件,导致/tmp/hsperfdata_${user}/${PID}文件没了,
user 例如 是admin root等等
pid就是 你当前运行的java的pid了。
顺便说下 如果jstat出现 pid not found ,那用jps也看不到这个进程了。
我这边因为是 这个pid文件被删除了,所以不能看了。
解决方法是重启服务就ok了
----------------------------
JVM 参数优化
-server -Xms2g -Xmx2g -XX:PermSize=96m -XX:MaxPermSize=256m -Xmn1024m -verbose:gc
-Xloggc:/home/yahoo/output/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
-XX:+UseConcMarkSweepGC
-XX:+DisableExplicitGC
参数 |
说明 |
-server |
服务机模式,不配置默认的是-client,一定要作为第一个参数,在多个CPU时性能佳 |
-Xms2g -Xmx2g |
堆大小,线上的堆的最大值与最小值必须一致,省得jvm调整堆大小浪费性能。 |
-Xmn1024m |
堆中新生代大小,一般为堆的一半多些 |
-XX:PermSize=96m -XX:MaxPermSize=256m |
jvm方法区空间大小 |
-Xloggc:/home/yahoo/output/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps |
打GC日志,这不会给系统带来啥负担,建议线上机器都加上,方便调优和OutOfMemory后查错。 |
-verbose:gc |
将虚拟机的垃圾回收事件信息打印 |
-XX:+UseConcMarkSweepGC |
新生代采用ParNew GC方式,旧生代采用并发GC方式,以减少系统停顿时间为优先,缩短major收集的时间,此选项在Heap Size 比较大而且Major收集时间较长的情况下使用更合适。 |
-XX:+DisableExplicitGC |
禁止程序触发GC |
-Xloggc:gc.log 指定垃圾收集日志文件
-XX:+UseParNewGC :缩短minor收集的时间
HeapDumpOnOutOfMemoryError
在jvm的 启动参数中追加 下列信息,可以在发生 OutOfMemoryError的时候生成 oom.hprof文件
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:/temp/oom.hprof
引自:http://blog.csdn.net/jiangguilong2000/article/details/8476361
相关推荐
标题中提到了JVM原理、JVM调优、JVM内存模型和JAVA并发,这些都是Java虚拟机(JVM)相关的核心概念。JVM是运行Java字节码的虚拟计算机,为Java提供了一个跨平台的环境,确保Java程序可以在不同的操作系统上运行而...
### 马士兵JVM调优笔记知识点梳理 #### 一、Java内存结构 Java程序运行时,其内存被划分为几个不同的区域,包括堆内存(Heap)、方法区(Method Area)、栈(Stack)、程序计数器(Program Counter Register)以及...
### JVM调优详解 #### 一、JVM调优概述 在现代软件开发中,Java虚拟机(JVM)作为Java应用程序的运行环境,对于提高应用程序的性能至关重要。JVM调优是指通过调整JVM的各种参数来优化Java应用程序的运行效率,减少...
在现代的软件开发与运行环境中,Java虚拟机(JVM)的性能调优是非常重要的一环,特别是在处理大型应用程序或者服务时,合适的JVM调优能够显著提升系统性能和稳定性。本篇文档详细介绍了JVM调优工具的命令使用及其...
在JVM调优实践中,了解各个运行时数据区的工作原理至关重要。以下是对这些区域的详细解析: 1. **虚拟机栈**:每个线程都有一个独立的虚拟机栈,用于存储方法调用时的栈帧。栈帧中包含局部变量表(存储方法中的变量...
《Monkey老师的JVM调优深度解析》 在Java开发领域,JVM(Java Virtual Machine)是每一个程序员都需要深入了解的关键组成部分。Monkey老师的JVM调优课程,无疑为我们提供了一个宝贵的平台,来深入探究JVM的工作原理...
JVM调优总结 -Xms -Xmx -Xmn -Xss JVM 调优是 Java virtual machine 的性能优化,通过调整 JVM 的参数来提高 Java 应用程序的性能。其中,-Xms、-Xmx、-Xmn、-Xss 是四个重要的参数,分别控制 JVM 的初始堆大小、...
《JVM调优实战解析》 在Java开发领域,JVM(Java Virtual Machine)是运行所有Java应用程序的基础,它的性能直接影响着程序的运行效率。因此,掌握JVM调优技术对于提升系统的稳定性和性能至关重要。本文将围绕"JVM...
### JVM调优与垃圾回收机制详解 #### 一、引言 随着软件系统的复杂度不断提高,性能优化成为了软件开发中的一个重要环节。对于Java应用程序来说,Java虚拟机(JVM)的性能直接影响着应用的整体表现。垃圾回收(GC)...
马老师 JVM 调优实战笔记 JVM 调优是 Java 开发者们不可或缺的技能,它直接影响着 Java 应用程序的性能和稳定性。本笔记是马老师的 JVM 调优实战笔记,涵盖了 JVM 的概述、内存结构、堆内存、垃圾回收算法、JVM ...
JVM调优是一个复杂的过程,它涉及到对Java虚拟机内部工作原理的深刻理解。本文档总结了JVM调优的基础知识和一些核心概念,旨在帮助开发者更好地掌握Java程序的性能优化。 首先,文档提到了Java中的数据类型分为基本...
JVM调优实战 本文档旨在介绍JVM调优实战的各个方面,包括JVM内存、垃圾回收、性能优化等。通过对JVM内存结构、垃圾回收机制和性能优化策略的详细讲解,帮助读者深入理解JVM的工作原理和优化方法。 1. JVM内存结构 ...
JVM面试资料。 JVM结构:类加载器,执行引擎,本地方法接口,本地内存结构; 四大垃圾回收算法:复制算法、标记-清除算法、标记-整理算法、分代收集算法 ...JVM调优:命令行指令,设置堆内存大小的参数
在深入讨论JVM(Java虚拟机)调优之前,我们有必要先了解一下虚拟机的基本概念和堆栈...通过上述的分析和总结,我们可以得出,JVM调优是一个涉及多方面知识的复杂过程,需要开发者具备扎实的理论基础和丰富的实践经验。
【JVM调优实战经验】 在Java开发中,JVM(Java Virtual Machine)的调优是提高应用程序性能的关键环节。JVM调优涉及到对内存管理、垃圾回收机制以及相关参数的调整,以优化应用程序的运行效率和稳定性。本文将深入...
分析常见的JVM调优技术及其相关条件,以及在实战中怎么使用到相关的技术进行调优,比较适合中高级开发进行学习,适合对JVM理解较深的开发学习
### JVM调优攻略 #### 一、概述 《JVM调优攻略》是一份详尽的文档,旨在帮助开发者理解并掌握Java虚拟机(JVM)的优化技巧。本指南不仅适用于初学者,对于有一定基础的开发人员来说也同样具有很高的参考价值。文档中...
《JVM调优实战》是一份深入探讨Java虚拟机(JVM)性能优化的文档,主要分为理论篇和实战篇两大部分。本文将详细解析其中的关键知识点。 理论篇首先介绍了JVM内存模型,将其比喻为一个多功能的养鱼塘。在这个比喻中...