一、配置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)当在server环境下(如Tomcat)启动并使用JVM时(对当前server环境下所以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进程。能够选择一个进行监控。假设要远程监控。则要在远程server的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命令使用方法:

  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内存状况。

以我本机为例,运行该命令,屏幕显示:

  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>

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

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

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

注意340是我本机的java进程pid。dump出来的文件比較大有10几M,并且我仅仅是开了tomcat。跑了一个非常easy的应用,且没有不论什么訪问,能够想象,大型繁忙的server上,dump出来的文件该有多大。须要知道的是,dump出来的文件信息是非常原始的,绝不适合人直接观看。而jmap -histo显示的内容又太简单,比如仅仅显示某些类型的对象占用多大内存。以及这些对象的数量,可是没有更具体的信息,比如这些对象各自是由谁创建的。那这么说,dump出来的文件有什么用呢?当然实用,由于有专门分析jvm的内存dump文件的工具。



5:jhat

上面说了,有非常多工具都能分析jvm的内存dump文件。jhat就是sun jdk6及以上版本号自带的工具,位于jdk的bin文件夹,运行 jhat -J -Xmx512m [file] ,file就是dump文件路径。jhat内置一个简单的webserver,此命令运行后,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比較了解的人,应该非常easy看懂这些信息,可是不清楚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毫秒

 如何选择工具

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

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

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

    前言 使用Hadoop进行离线分析或者数据挖掘的project师,常常会须要对Hadoop集群或者mapreduce作业进行性能调优. 或许你知道通过浏览器訪问http://master:18088/ ...

  2. jvm内存查看方法----个人参考版

    查看设置JVM内存信息 1 Runtime.getRuntime().maxMemory(); //最大可用内存,对应-Xmx 2 3 Runtime.getRuntime().freeMemory( ...

  3. aix 查看内存,CPU 配置信息

    内存lsattr -El mem0cpu lsdev -C |grep procCPU的信息lsattr -El proc0   #bootinfo -r查看物理内存     使用命令#  lsdev ...

  4. linux内存查看工具

    这里帮你总结了一下Linux下查看内存使用情况的多种方法~ 在做 Linux 系统优化的时候,物理内存是其中最重要的一方面.自然的,Linux 也提供了非常多的方法来监控宝贵的内存资源的使用情况.下面 ...

  5. 【Android】开发优化之——调优工具:dump hprof file 查看内存情况,找到内存泄露

    虽说知道一般性的开发android应用须要注意的问题,但是也有水平參差不齐的情况.特别是维护代码,假设内存占用大,内存溢出严重,又怎么解决呢?  --  通过DDMS把heap抓出来分析 1.打开DD ...

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

    SysInternals提供了一个工具RamMap,可以查看内存的具体使用情况.如果发现是Paged Pool和Nonpaged Pool占用过大,可以用另一个工具poolmon来查看占用内存的驱动T ...

  7. Linux进程管理——查看内存的工具

    Linux进程管理——查看内存的工具 一查看内存的工具vmstat vmstat命令:虚拟内存信息vmstat [options] [delay [count]]vmstat 2 5 [root@ce ...

  8. 查看服务器硬件配置信息(cpu/内存)

    1.查看cpu情况: 方法一:   Linux下CPU相关的参数保存在 /proc/cpuinfo 文件里   cat /proc/cpuinfo |more   方法二:   采用命令 dmesg ...

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

    查看内存 命令 free  默认是k为单位 也可以指定 m为单位 或者G为单位,这个不精准 total 总容量 used  使用了多少 free  剩余多少 看第二行.第一行是物理内存,加上虚拟内存b ...

随机推荐

  1. robotframework ride 版本兼容问题

    在安装robotFramework ride的时候,必须需要使用wxpython 目前使用的wxpython 还必须是unicode 版本的要不然不支持中文 目前使用的 wx.version.2.8. ...

  2. Tomcat 用户配置

    如果你没有改变任何配置文件,请检查文件conf / tomcat用户.xml在你安装.该文件必须包含凭证让你使用这个应用. 例如,添加一个用户名为tomcat manager gui角色s3cret密 ...

  3. android在其他线程中访问UI线程的方法

    1.Activity.runOnUiThread( Runnable ) 2.View.post( Runnable ) 3.View.postDelayed( Runnable, long ) 4. ...

  4. 理解 Thread.Sleep 函数

    我们可能经常会用到 Thread.Sleep 函数来使线程挂起一段时间.那么你有没有正确的理解这个函数的用法呢?思考下面这两个问题: 假设现在是 2008-4-7 12:00:00.000,如果我调用 ...

  5. HDU 1254 推箱子游戏(搞了一下午。。。)

    中文题目:http://acm.hdu.edu.cn/showproblem.php?pid=1254 一开始常规的人用来做主导,想着想着不对劲,其实是箱子为主导,人只是箱子能否推进的一个判断. 可以 ...

  6. Windows DIB文件操作具体解释-5.DIB和调色板

    Windows调色板是256色显卡时期的产物,如今显卡最少也是16bit的了.所以调色板基本上是用不到了的. 可是以下几种情况还是须要去使用和了解调色板: 1.在新显卡上保证256色兼容模式的正常执行 ...

  7. 开源中国IOSclient

    我想看看别人开发项目.通过吸收经验,然后找到开放的中国,丹尼尔一些网上也开发了自己的开源在中国client 在网上看到很多网友说,不能下载东西像安装,我带来了我的方式,其中的一些朋友想帮忙. http ...

  8. CloseHandle(),TerminateThread(),ExitThread()的差别

    线程的handle用处: 线程的handle是指向"线程的内核对象"的,而不是指向线程本身.每一个内核对象仅仅是内核分配的一个内存块,而且仅仅能由内核訪问.该内存块是一种数据结构, ...

  9. 第四章 Spring与JDBC的整合

    这里选择的是mysql数据库. 4.1引入aop.tx的命名空间 为了事务配置的需要,我们引入aop.tx的命名空间 <?xml version="1.0" encoding ...

  10. 深入分析redis cluster 集群

    深入分析redis cluster 集群安装配置详解 下面小编来为各位介绍一篇深入分析redis cluster 集群安装配置详解,如果你希望做数据库集群就可以来看看此文章的哦. http://rub ...