配置JVM内存 查看内存工具

一、配置JVM内存

1.配置JVM内存的参数有四个:

-XmxJavaHeap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定;

-XmsJavaHeap初始值,Server端JVM最好将-Xms和-Xmx设为相同值,开发测试机JVM可以保留默认值;

-XmnJavaHeapYoung区大小,不熟悉最好保留默认值;

-Xss每个线程的Stack大小,不熟悉最好保留默认值;

2.如何配置JVM内存分配:

(1)当在命令提示符下启动并使用JVM时(只对当前运行的类Test生效):

java-Xmx128m-Xms64m-Xmn32m-Xss16mTest

(2)当在集成开发环境下(如eclipse)启动并使用JVM时:

a.在eclipse根目录下打开eclipse.ini,默认内容为(这里设置的是运行当前开发工具的JVM内存分配):

-vmargs-Xms40m-Xmx256m-vmargs表示以下为虚拟机设置参数,可修改其中的参数值,也可添加-Xmn,-Xss,另外,eclipse.ini内还可以设置非堆内存,如:-XX:PermSize=56m,-XX:MaxPermSize=128m。

此处设置的参数值可以通过以下配置在开发工具的状态栏显示:

在eclipse根目录下创建文件options,文件内容为:org.eclipse.ui/perf/showHeapStatus=true

修改eclipse根目录下的eclipse.ini文件,在开头处添加如下内容:

-debugoptions-vmjavaw.exe重新启动eclipse,就可以看到下方状态条多了JVM信息。

b.打开eclipse-窗口-首选项-Java-已安装的JRE(对在当前开发环境中运行的java程序皆生效)

编辑当前使用的JRE,在缺省VM参数中输入:-Xmx128m-Xms64m-Xmn32m-Xss16m

c.打开eclipse-运行-运行-Java应用程序(只对所设置的java类生效)

选定需设置内存分配的类-自变量,在VM自变量中输入:-Xmx128m-Xms64m-Xmn32m-Xss16m

注:如果在同一开发环境中同时进行了b和c设置,则b设置生效,c设置无效,如:

开发环境的设置为:-Xmx256m,而类Test的设置为:-Xmx128m-Xms64m,则运行Test时生效的设置为:

-Xmx256m-Xms64m

(3)当在服务器环境下(如Tomcat)启动并使用JVM时(对当前服务器环境下所以Java程序生效):

a.设置环境变量:

变量名:CATALINA_OPTS

变量值:-Xmx128m-Xms64m-Xmn32m-Xss16m

b.打开Tomcat根目录下的bin文件夹,编辑catalina.bat,将其中的%CATALINA_OPTS%(共有四处)替换为:-Xmx128m-Xms64m-Xmn32m-Xss16m

二、查看配置JVM内存信息

Runtime.getRuntime().maxMemory();//最大可用内存,对应-Xmx

Runtime.getRuntime().freeMemory();//当前JVM空闲内存

Runtime.getRuntime().totalMemory();//当前JVM占用的内存总数,其值相当于当前JVM已使用的内存及freeMemory()的总和

关于maxMemory(),freeMemory()和totalMemory():

maxMemory()为JVM的最大可用内存,可通过-Xmx设置,默认值为物理内存的1/4,设值不能高于计算机物理内存;

totalMemory()为当前JVM占用的内存总数,其值相当于当前JVM已使用的内存及freeMemory()的总和,会随着JVM使用内存的增加而增加;

freeMemory()为当前JVM空闲内存,因为JVM只有在需要内存时才占用物理内存使用,所以freeMemory()的值一般情况下都很小,而JVM实际可用内存并不等于freeMemory(),而应该等于maxMemory()-totalMemory()+freeMemory()。及其配置JVM内存分配。

业界有很多强大的java profile的工具,比如Jporfiler,yourkit,这些收费的东西我就不想说了,想说的是,其实java自己就提供了很多内存监控的小工具,下面列举的工具只是一小部分,仔细研究下jdk的工具,还是蛮有意思的呢:)

1:gc日志输出

在jvm启动参数中加入 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintGCApplicationStopedTime,jvm将会按照这些参数顺序输出gc概要信息,详细信息,gc时间信息,gc造成的应用暂停时间。如果在刚才的参数后面加入参数 -Xloggc:文件路径,gc信息将会输出到指定的文件中。其他参数还有

-verbose:gc和-XX:+PrintTenuringDistribution等。

2:jconsole

jconsole是jdk自带的一个内存分析工具,它提供了图形界面。可以查看到被监控的jvm的内存信息,线程信息,类加载信息,MBean信息。

jconsole位于jdk目录下的bin目录,在windows下是jconsole.exe,在unix和linux下是jconsole.sh,jconsole可以监控本地应用,也可以监控远程应用。 要监控本地应用,执行jconsole pid,pid就是运行的java进程id,如果不带上pid参数,则执行jconsole命令后,会看到一个对话框弹出,上面列出了本地的java进程,可以选择一个进行监控。如果要远程监控,则要在远程服务器的jvm参数里加入一些东西,因为jconsole的远程监控基于jmx的,关于jconsole详细用法,请见专门介绍jconsle的文章,我也会在博客里专门详细介绍jconsole。

3:jviusalvm

在JDK6 update 7之后,jdk推出了另外一个工具:jvisualvm,java可视化虚拟机,它不但提供了jconsole类似的功能,还提供了jvm内存和cpu实时诊断,还有手动dump出jvm内存情况,手动执行gc。

和jconsole一样,运行jviusalvm,在jdk的bin目录下执行jviusalvm,windows下是jviusalvm.exe,linux和unix下是jviusalvm.sh。

4:jmap

jmap是jdk自带的jvm内存分析的工具,位于jdk的bin目录。jdk1.6中jmap命令用法:

Html代码

  1. Usage:
  2. jmap -histo <pid> (to connect to running process and print histogram of java object heap
  3. jmap -dump:<dump-options> <pid>  (to connect to running process and dump java heap)
  4. dump-options: format=b binary default file=<file>
  5. dump heap to <file>
  6. Example: jmap -dump:format=b,file=heap.bin <pid>
<span style="font-size:18px;">Usage:
jmap -histo <pid> (to connect to running process and print histogram of java object heap
jmap -dump:<dump-options> <pid>  (to connect to running process and dump java heap)
dump-options: format=b binary default file=<file>
dump heap to <file>
Example: jmap -dump:format=b,file=heap.bin <pid> </span>

jmap -histo <pid>在屏幕上显示出指定pid的jvm内存状况。以我本机为例,执行该命令,屏幕显示:

Html代码

  1. 1:         24206        2791864  < constMethodKlass >
  2. 2:         22371        2145216  [C
  3. 3:         24206        1940648  < methodKlass >
  4. 4:          1951        1364496  < constantPoolKlass >
  5. 5:         26543        1282560  < symbolKlass >
  6. 6:          6377        1081744  [B
  7. 7:          1793         909688  < constantPoolCacheKlass >
  8. 8:          1471         614624  < instanceKlassKlass >
  9. 9:         14581         548336  [Ljava.lang.Object;
  10. 10:          3863         513640  [I
  11. 11:         20677         496248  java.lang.String
  12. 12:          3621         312776  [Ljava.util.HashMap$Entry;
  13. 13:          3335         266800  java.lang.reflect.Method
  14. 14:          8256         264192  java.io.ObjectStreamClass$WeakClassKey
  15. 15:          7066         226112  java.util.TreeMap$Entry
  16. 16:          2355         173304  [S
  17. 17:          1687         161952  java.lang.Class
  18. 18:          2769         150112  [[I
  19. 19:          3563         142520  java.util.HashMap
  20. 20:          5562         133488  java.util.HashMap$Entry
  21. Total        239019       17140408
<span style="font-size:18px;">1:         24206        2791864  < constMethodKlass >
2:         22371        2145216  [C
3:         24206        1940648  < methodKlass >
4:          1951        1364496  < constantPoolKlass >
5:         26543        1282560  < symbolKlass >
6:          6377        1081744  [B
7:          1793         909688  < constantPoolCacheKlass >
8:          1471         614624  < instanceKlassKlass >
9:         14581         548336  [Ljava.lang.Object;
10:          3863         513640  [I
11:         20677         496248  java.lang.String
12:          3621         312776  [Ljava.util.HashMap$Entry;
13:          3335         266800  java.lang.reflect.Method
14:          8256         264192  java.io.ObjectStreamClass$WeakClassKey
15:          7066         226112  java.util.TreeMap$Entry
16:          2355         173304  [S
17:          1687         161952  java.lang.Class
18:          2769         150112  [[I
19:          3563         142520  java.util.HashMap
20:          5562         133488  java.util.HashMap$Entry
Total        239019       17140408 </span>

为了方便查看,我删掉了一些行。从上面的信息很容易看出,#instance指的是对象数量,#bytes指的是这些对象占用的内存大小,class name指的是对象类型。

再看jmap的dump选项,这个选项是将jvm的堆中内存信息输出到一个文件中,在我本机执行

jmap -dump:file=c:\dump.txt 340

注意340是我本机的java进程pid,dump出来的文件比较大有10几M,而且我只是开了tomcat,跑了一个很简单的应用,且没有任何访问,可以想象,大型繁忙的服务器上,dump出来的文件该有多大。需要知道的是,dump出来的文件信息是很原始的,绝不适合人直接观看,而jmap -histo显示的内容又太简单,例如只显示某些类型的对象占用多大内存,以及这些对象的数量,但是没有更详细的信息,例如这些对象分别是由谁创建的。那这么说,dump出来的文件有什么用呢?当然有用,因为有专门分析jvm的内存dump文件的工具。

5:jhat

上面说了,有很多工具都能分析jvm的内存dump文件,jhat就是sun jdk6及以上版本自带的工具,位于jdk的bin目录,执行 jhat -J -Xmx512m [file] ,file就是dump文件路径。jhat内置一个简单的web服务器,此命令执行后,jhat在命令行里显示分析结果的访问地址,可以用-port选项指定端口,具体用法可以执行jhat -heap查看帮助信息。访问指定地址后,就能看到页面上显示的信息,比jmap
-histo命令显示的丰富得多,更为详细。

6:eclipse内存分析器

上面说了jhat,它能分析jvm的dump文件,但是全部是文字显示,eclipse memory analyzer,是一个eclipse提供用于分析jvm 堆dump的插件,网址为
http://www.eclipse.org/mat,它的分析速度比jhat快,分析结果是图形界面显示,比jhat的可读性更高。其实jvisualvm也可以分析dump文件,也是有图形界面显示的。

7:jstat

如果说jmap倾向于分析jvm内存中对象信息的话,那么jsta就是倾向于分析jvm内存的gc情况。都是jvm内存分析工具,但显然,它们是从不同维度来分析的。jsat常用的参数有很多,如 -gc,-gcutil,-gccause,这些选项具体作用可查看jsat帮助信息,我经常用-gcutil,这个参数的作用不断的显示当前指定的jvm内存的垃圾收集的信息。

我在本机执行 jstat -gcutil 340 10000,这个命令是每个10秒钟输出一次jvm的gc信息,10000指的是间隔时间为10000毫秒。屏幕上显示如下信息(我只取了第一行,因为是按的一定频率显示,所以实际执行的时候,会有很多行):

S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT

54.62   0.00  42.87  43.52  86.24   1792    5.093    33    7.670   12.763

额。。。怎么说呢,要看懂这些信息代表什么意思,还必须对jvm的gc机制有一定的了解才行啊。其实如果对sun的 hot spot jvm的gc比较了解的人,应该很容易看懂这些信息,但是不清楚gc机制的人,有点莫名其妙,所以在这里我还是先讲讲sun的jvm的gc机制吧。说到gc,其实不仅仅只是java的概念,其实在java之前,就有很多语言有gc的概念了,gc嘛就是垃圾收集的意思,更多的是一种算法性的东西,而跟具体语言没太大关系,所以关于gc的历史,gc的主流算法我就不讲了,那扯得太远了,扯得太远了就是扯淡。sun现在的jvm,内存的管理模型是分代模型,所以gc当然是分代收集了。分代是什么意思呢?就是将对象按照生命周期分成三个层次,分别是:新生代,旧生代,持久代。对象刚开始分配的时候,大部分都在新生代,当新生代gc提交被触发后了,执行一次新生代范围内的gc,这叫minor
gc,如果执行了几次minor gc后,还有对象存活,将这些对象转入旧生代,因为这些对象已经经过了组织的重重考验了哇。旧生代的gc频率会更低一些,如果旧生代执行了gc,那就是full gc,因为不是局部gc,而是全内存范围的gc,这会造成应用停顿,因为全内存收集,必须封锁内存,不许有新的对象分配到内存,持久代就是一些jvm期间,基本不会消失的对象,例如class的定义,jvm方法区信息,例如静态块。需要主要的是,新生代里又分了三个空间:eden,susvivor0,susvivor1,按字面上来理解,就是伊甸园区,幸存1区,幸存2区。新对象分配在eden区中,eden区满时,采用标记-复制算法,即检查出eden区存活
的对象,并将这些对象复制到是s0或s1中,然后清空eden区。jvm的gc说开来,不只是这么简单,例如还有串行收集,并行收集,并发收集,还有著名的火车算法,不过那说得太远了,现在对这个有大致了解就好。说到这里,再来看一下上面输出的信息:

S0       S1       E        O          P       YGC     YGCT    FGC    FGCT     GCT

54.62   0.00  42.87  43.52  86.24   1792    5.093    33    7.670   12.763

S0:新生代的susvivor0区,空间使用率为54..62%

S1:新生代的susvivor1区,空间使用率为0.00%(因为还没有执行第二次minor收集)

E:eden区,空间使用率42.87%

O:旧生代,空间使用率43.52%

P:持久带,空间使用率86.24%

YGC:minor gc执行次数1792次

YGCT:minor gc耗费的时间5.093毫秒

FGC:full gc执行次数33

FGCT:full gc耗费的时间7.670毫秒

GCT:gc耗费的总时间12.763毫秒

 怎样选择工具

上面列举的一些工具,各有利弊,其实如果在开发环境,使用什么样的工具是无所谓的,只要能得到结果就好。但是在生产环境里,却不能乱选择,因为这些工具本身就会耗费大量的系统资源,如果在一个生产服务器压力很大的时候,贸然执行这些工具,可能会造成很意外的情况。最好不要在服务器本机监控,远程监控会比较好一些,但是如果要远程监控,服务器端的启动脚本要加入一些jvm参数,例如用jconsloe远程监控tomcat或jboss等,都需要设置jvm的jmx参数,如果仅仅只是分析服务器的内存分配和gc信息,强烈推荐,先用jmap导出服务器端的jvm的堆dump文件,然后再用jhat,或者jvisualvm,或者eclipse内存分析器来分析内存状况。

配置JVM内存 查看内存工具

时间: 2024-08-25 01:38:57

配置JVM内存 查看内存工具的相关文章

Hadoop2.6.0配置參数查看小工具

前言 使用Hadoop进行离线分析或者数据挖掘的project师,常常会须要对Hadoop集群或者mapreduce作业进行性能调优. 或许你知道通过浏览器訪问http://master:18088/conf来查看配置信息.例如以下图所看到的: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" /> 但是

虚拟机常用的内存查看与分析工具

内存查看与分析工具,下面是日常监控可以使用的一些工具, 在调试时应用比较多的是堆栈信息,查看这篇文章: Java Thread Dump 性能分析 gc日志输出 在jvm启动参数中加入 1 2 3 4 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintGCApplicationStopedTime jvm将会按照这些参数顺序输出gc概要信息,详细信息,gc时间信息,gc造成的应用暂停时间.如果在刚才的参数后面加入参

aix 查看内存,CPU 配置信息

内存lsattr -El mem0cpu lsdev -C |grep procCPU的信息lsattr -El proc0 #bootinfo -r查看物理内存 使用命令#  lsdev -Cc memory查看配置的物理内存设备,下面为其输出示例:  mem0 Available 00-00 Memory   L2cache0 Available 00-00 L2 Cache 再使用命令# lsattr -El mem0输出如下  size 512 Total amount of physi

SysInternals提供了一个工具RamMap,可以查看内存的具体使用情况

SysInternals提供了一个工具RamMap,可以查看内存的具体使用情况.如果发现是Paged Pool和Nonpaged Pool占用过大,可以用另一个工具poolmon来查看占用内存的驱动Tag是什么,然后再用Tag找到对应的驱动,可以尝试更新驱动,或者用Autoruns禁止其启动. 微软应该不会那么SB,专门开发一个拖累系统的功能吧……可能是某个后台服务/驱动有Bug导致内存占用异常.以前还碰到过迅雷的XLServicePlatform服务占用超大(数GB)内存的现象,可能是因为这个

linux日常管理-free查看内存工具

查看内存 命令 free  默认是k为单位 也可以指定 m为单位 或者G为单位,这个不精准 total 总容量 used  使用了多少 free  剩余多少 看第二行.第一行是物理内存,加上虚拟内存buffers和cached 等于free第二行实际的剩余内存 buffers 数据将要写入到磁盘里去的 cached 数据从磁盘里取出来,放到内存里存. /////////////////////////////////////////////////////////////////////////

jstack(查看线程)、jmap(查看内存)和jstat(性能分析)命令

公司内部同事分享的一篇文章 周末看到一个用jstack查看死锁的例子.昨天晚上总结了一下jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令.供大家参考 1.Jstack 1.1   jstack能得到运行java程序的java stack和native stack的信息.可以轻松得知当前线程的运行情况.如下图所示 注:这个和thread dump是同样的结果.但是thread dump是用kill -3 pid命令,还是服务器上面少用kill为妙 1.2   命名行格式

java内存查看与分析

业界有很多强大的java profile的工具,比如Jporfiler,yourkit,这些收费的东西我就不想说了,想说的是,其实java自己就提供了很多内存监控的小工具,下面列举的工具只是一小部分,仔细研究下jdk的工具,还是蛮有意思的呢:) 1:gc日志输出 在jvm启动参数中加入 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintGCApplicationStopedTime,jvm将会按照这些参数顺序输出g

[转]JVM运行时内存结构

目录[-] 1.为什么会有年轻代 2.年轻代中的GC 3.一个对象的这一辈子 4.有关年轻代的JVM参数 1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用,这样就会对堆的所有区域进行扫描.而我们的很多对象都是朝生夕死的,如果分代的话,我们把新创建的对象放到某一地方,当GC的时候先把这块存“朝生夕死”对象的区域进行回收,这样就会

JVM模型及内存溢出

一.JVM截图及概念 图1:JVM虚拟机运行时数据区域概念模型 1.程序计数器:内存空间中的一块小区域,作为当前线程所执行的字节码的行号指示器,注:如果是native方法,计数器为空 2.虚拟机栈:线程私有,生命周期与线程相同,虚拟机栈描述的是Java方法执行的内存模型:创建栈帧,用于存储局部变量表.操作数栈.动态链接.方法出口等信息 3.本地方法栈:和虚拟机栈功能类似,虚拟机使用本地Native方法服务 4.Java堆:线程共享,用于存放对象,是GC的主要管理区域 5.方法区:线程共享,用于存