理解JAVA虚拟机(下)

时间:2021-10-27 05:16:05

2016-04-18 20:40:59

三、JVM内存参数调整及监控

3.1  JVM之内存调整

JVM运行时数据区的内存大小可以通过参数来设置,通常能设置的两块区域为堆空间和持久代(方法区),设置方法是以参数的形式来指定, Sun 的HotSpot需要在jvm启动前设置这些参数,启动JVM后不能动态改变其大小。

JVM参数说明:

-Xms300m: 堆空间初始大小

-Xmx1g : 堆空间最大值(生产环境一般该值与Xms值设为一致,这样可以避免每次垃圾回收完成后对JVM堆大小进行重新调整)

-Xmn512M:  堆空间年轻代大小

-XX:NewRatio=4:  JVM堆的年轻代和老年代的大小比例为1:4

-Xss128K: 每个线程的堆栈大小为128K

-XX:SurvivorRatio=6:  新生代Surivor区(新生代有2个Surivor区)和Eden区的比例为2:6

-XX:PermSize=150M :  持久代初始大小

-XX:MaxPermSize=150M:  持久代最大值

-XX:MaxTenuringThreshold=1:新 生代的对象经过几次垃圾回收后(如果还存活),进入老年代。如果该参数设置为0,这表示新生代的对象在垃圾回收后,不进入survivor区,直接进入老年代

-XX:+HeapDumpOnOutOfMemoryError: 该参数表示当JVM发生内存溢出时,自动在程序目录下生成DUMP文件,通过该文件可以分析出什么原因导致内存溢出的

不同的JAVA程序设置参数的地方不一样,但参数名称是一样的。例:

1、启动一般JAVA程序可以使用以下方式设置启动时的jvm参数

JAVA -Xms2g -Xmx2g -Xmn512M -Xss128K -XX:PermSize=128M -XX:MaxPermSize=128M

-XX:NewRatio=4 -XX:SurivorRatio=4 -XX:MaxTenuringThreshold=1

2、 设置eclipse的jvm参数一般是在eclipse安装目录下的eclipse.ini文件中;

3、 设置tomcat5的jvm参数是在tomcat的bin目录下的catalina.bat文件中;

注: JVM堆空间的最大能分配多少与操作系统及硬件配置有关, 32位的操作系统一般为2g以下, 64位的操作系统基本可以说是没限制。

当前操作系统最大能给jvm分配多少内存可以通过在命令行窗口使用“ java -Xmx1200m” 测试出来。

3.2  JVM之监控工具--Jconsole

了解了如何设置jvm内存后,那又如何对jvm进行监控呢,以确保设置的参数正确呢,我们可以借助sun Jdk自带的Jconsole监控工具监控jvm的堆空间大小及使用情况。具体步骤如下:

第一步、配置jvm监控参数

该参数需在jvm启动前配置,其配置方法及位置同设置jvm堆大小方法一样.

具体参数及说明如下:

-DJAVA.rmi.server.hostname=127.0.0.1:指定当前主机的IP

-Dcom.sun.management.jmxremote.port=9880:指定使用那个端口作为监控的端口

-Dcom.sun.management.jmxremote.ssl=false :

-Dcom.sun.management.jmxremote.authenticate=false:不需要使用口令

第二步、运行JVM监控工具Jconsole

在命令行窗口输入“ jconsole”并回车即可(前提是配置了JAVA环境变量,如果未配置可以进入到jdk的bin目录下手动执行“ jconsole.exe”程序)

第三步、选择需要监控的jvm

1、监控本地JVM

直接选中本地的JAVA进程,点连接即可

2、监控远程JVM

先选择远程监控,并在文本框中填写远程jvm的ip地址及监控端口号,如果远程jvm开启口令认证的话还需要输入用户名和口令

3.3 JVM之监控工具--Jprofile

Jprofile是一个功能强大且最好的JAVA剖析工具,专用于J2SE和JAVAEE应用程序监控分析。

Jprofile支持监控多种不同厂商的JVM,并可与IDE等流行的应用服务器整合进行JVM监控、分析内存泄漏问题,找出系统的性能瓶颈。

Jprofile既能监控本地的JAVA应用程序也能监控远程的JAVA程序。

Jprofile需要商业授权才能使用,一般会提供试用版的。

四、JVM实战

4.1  JVM垃圾回收

(1)垃圾回收概念

什么是垃圾回收:

JVM中自动检测并移除不再使用的数据对象的这种机制称为:垃圾回收(Garbage Collection ),简称GC。

GC的基本原理:

JVM通过使用垃圾收集器及使用相应的垃圾回收算法将内存中不再被使用的对象进行回收。

为什么要垃圾回收:

由于不同JAVA对象存活时间是不一定的,因此,在程序运行一段时间以后,如果不进行垃圾回收,整个程序会因内存耗尽导致整个程序崩溃。垃圾回收还会整理那些零散的内存碎片,碎片过多最直接的问题就是会导致无法分配大块的内存空间以及降低程序的运行效率。

那些区域会被GC:

VM栈、本地方法栈以及程序计数器会随方法或线程的结束而自然被回收,所以这些区域不需要考虑回收问题。

堆空间和持久代(方法区)是GC回收的重点区域,不同区域对象的收集叫法不一样

( 1)对年轻代的对象的收集称为minor GC,

( 2)对老年代的对象的收集称为Full GC。程序中主动调用System.gc()强制执行的GC为Full GC。

(2)垃圾收集算法

标记清除算法:

复制算法:

标记整理算法:

分代收集算法:

(3)垃圾收集器

如果说收集算法是内存回收的方法论,垃圾收集器就是内存回收的具体实现,不同的垃圾收集器有不同的内存回收算法(引用计数、标记-清除算法、复制算法、标记-整理算法等)。 jvm规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商、不同版本的jvm所提供的垃圾收集器都可能 会有很大的差别,并且一般都会提供参数供用户根据自己的应用特点和要求组合出各个年代所使用的收集器。