JVM内存结构及其调优(上)——Java虚拟机结构和属性

来源:互联网 发布:游乐网软件下载 编辑:程序博客网 时间:2024/06/08 12:21

Java程序员都知道虚拟机很重要,基于Java、Tomcat开发的应用是经常出现OOM(OutOfMemoryError)的错误,即内存溢出,分下面三种情况;

java.lang.StackOverflowError://很少java.lang.OutOfMemoryError://heap Space(比较常见)java.lang.OutOfMemoryError://PermGen Space(经常出现)

出现这种我们不要一味的想着增加内存来满足,很多时候加内存是杯水车薪,而是掌握JVM的内部结构、内存管理、垃圾收集机制,才能有效的控制JVM的运行,达到JVM的调优才是硬道理。
从以下几部分来掌握:
(1)、Java虚拟机结构和属性
(2)、JVM垃圾回收机制:包括2种垃圾回收方法,7种垃圾收集器
(3)、JVM内存区域分配:包括堆、新生代、老年代、永久代,新生代子空间。

一、Java虚拟机结构和属性
Java的内存区叫做堆(Heap),用来保存Java类和对象的物理区域。
1、 Java虚拟机内存结构
Java 虚拟机的堆被分为3 个称为域(Generation) 的主要部分,它们对应于对象的不同生存期,如图2-1所示。3 个域分别是新域(YoungGeneration)、旧域(TenuredGeneration) 和永久域(PermGeneration),标记为Virtual 的部分被保留,在必要时才实际分配出去。

新域(YoungGeneration) 由Eden 和两个救助空间Survivor 组成。新对象通常创建于Eden 中。其中一个救助空间Survivor 会随时被清空,并用做另一个救助空间Survivor 的目的地。当进行垃圾收集时,所有来自Eden 和救助空间Survivor 的活动对象都被复制到另一个救助空间Survivor。对象在两个救助空间Survivor 之间移动,直到它们足够“老”,能够被移入保存生存期较长对象的旧域(Tenured Generation) 中。
这里写图片描述
永久代(Perm Generation)用来保存那些在虚拟机的整个生命期都生存的对象。
2、Java虚拟机配置选项

JVM性能调优其实就是对JVM的内存进行调整和控制,包括堆(heap)大小的调整,Generation大小的调整、垃圾程序的选择。
-X选项:在JDK升级时不会通知更改
-XX选项:不够稳定,建议少用。
其中-X选项和-XX选项可以设计如下三种类型的属性值:
Boolean值:-XX:+<option>表示打开属性,-XX:-<option>表示关闭该属性。

Numeric值:-XX:<option>=<number>,其中的数字可以包含表示字节的字母,k和K表示KB,m和M表示MB,g和G表示GB,不加字母默认为Byte。

String值:-XX:<option>=<string>,通常用于制定一个文件名、路径名、命令列表等。
3、属性
下面列出一些常用的-X属性和-XX属性
3.1 -X 属性列表

属性列表及其默认值
描述

-Xint
只在解释(inteperated) 模式下运行虚拟机。如果使用这个选项,系统将不编译任何字节码

-Xbatch
通常JVM会预编译代码,结束后再在JIT中执行,该属性用于禁止预编译,直接在JIT中执行编译和运行

-Xdebug
启用JVMDI Debug 支持,在J2SE 5.0 中已经不再支持该属性

-Xootlasspath:botlasspath
指定一个目录及JAR和ZIP档案的列表,作为搜索启动类的范围。列表中各项之间的分隔符为冒号(:)

-Xbootlasspath/a:path
指定带“/”分隔符的路径,包含了JAR和ZIP档案,追加在默认clsspath后

-Xbootlasspath/p:path
指定带“/”分隔符的路径,包含了JAR和ZIP档案,追加在默认classpath之前

-Xcheck:jni
执行JNI功能,检查传递给JNI的参数,如果参数不合法将终止JNI调用

-Xfuture
对类文件执行严格的格式检查。这个选项强制Java对是否遵守类文件规范做更加严格的检查,而默认的检查只是基于Java1.1.x的标准。你应该使用这个选项来对代码进行测试,以便确保这些代码在未来的Java版本中能够工作,这些未来的版本可能强制进行更为严格的类文件格式检查

-Xnoclassge
禁用垃圾回收

-Xincge
启用增量垃圾收集器

-Xloggc :file
记录垃圾回收日志到file 文件中,file 为一个本地文件的地址

-Xmn
为Eden对象设定初始Java堆的大小,默认值为640KB

-Xmsn
设定Java堆的初始尺寸,默认尺寸是2097152 (2MB)。这个值必须是1024字节1KB)的倍数,且比它大

-Xmxn
设定Java 堆的最大尺寸,默认值为64MB,最大的堆尺寸达到将近2GB 2048MB )。请注意: 很多垃圾收集器的选项依赖于堆大小的设定。请在微调垃圾收集器使用内存空间的方式之前,确认是否已经正确设定了堆的尺寸

-Xprof
把运行程序详细的行为分析数据发送给标准输出。在产品级的代码中不能使用这个选项

-Xrunhprof [:help]
启用CPU、内存和监视器记录

-Xrs
降低JVM的系统信号使用率,JVM能够监视控制台事件,如果监控到CTRL_C_EVENT、CTRL_CLOSE_EVENT、CTRL_LOGOFF_EVENT、CTRL_SHUTDOWN_EVENT B 5,将停止JVM 的运行

-Xssn
设置线程堆栈大小为n

3.2 -XX属性的类型
(1)JVM行为控制属性–垃圾收集器的选择、GC的时机等

属性列表及其默认值
描述

-XX:-AllowUserSignalHandlers
仅与Solaris和Linux系统相关,启用信号处理器

-XX :AltStackSize=16384
仅与Solaris和Linux系统相关,指定信号处理器堆栈大小

-XX:-DisableExplicitGC
忽略代码中对Sysem.gcO的显式调用,虚拟机仍然按照正常的机制进行垃圾收集。这个选项禁止在代码中强制执行垃圾收集

-XX :+ FailOverToOldVerifer
当新建类型检查失败时,转移到旧对象

-XX: + HandlePromotionFailure
新域不需要为活动对象增大权限

-XX: +MaxFDLimit
仅与Solaris系统相关,提高文件描述符的数量到最大

-XX:PreBlockSpin= 10
当使用-XX:+UseSpinning 属性时,设置线程同步代码的最大数量

-XX:-RelaxAccessControlCheck
释放访问控制器的验证检查

-XX + SeavengeBeforeFullGC
设置新域的GC 为最优先

XX + UseAltSigs
仅与Solaris 系统相关,使用可选的信号代替SIGUSRI 和SIGUSR2

-XX:+UseBoundThreads
仅与Solaris系统相关,将用户级别与内核线程绑定

-XX :-UseConcMarkSweepGC
激活标志和清除同时进行的垃圾收集活动,这个选项对多处理器的计算机有效

-XX:+UseGCOverheadLimit
在OutOfMemory错误产生之前,限制JVM 的GC回收时间

-XX +UseLW PSynchronization
仅与Solaris 系统相关,使用LWP代替线程同步机制

-XX:-UseParallelGC
激活并行的垃圾收集活动,这个选项只对多处理器的计算机有效

-XX :- seParallelOldGC
使用并行垃圾收集器

-XX :-UseSerialGC
使用串行垃圾收集器

-XX:-UseSpinning
在进入操作系统的线程同步前,使用Java监视

-XX:+UseTLAB
激活线程本地的分配缓存区。使用这个缓存区将使线程任务繁重的应用程序的内存分配更加具有可扩展性,大大提高内存分配的性能

-XX +UseSplitVerifier
使用对堆栈映射表的属性实行新对象检查

-XX: + UseThreadPriorities
使用本地线程优先级

-XX:+UseVMInterruptiblelO
仅与Solaris系统相关,遇到系统IO操作的EINTR错误时终止线程

(2)JVM性能调优属性–永久域大小、新域大小和上限等

属性列表及其默认值
述描

-XX:+AggressiveOpts
启用性能编译器检查点

-XX :CompileThreshold=10000
在编译开始前改变方法调用(程序分支) 的数目

-XX:LargePageS izel nBytes=4m
设置Java堆的最大页大小

-XX:MaxHeapFreeRatio=70
改变垃圾回收之后和堆内存缩小之前可用堆内存的最大百分比,默认值为70。这意味着如果在垃圾回收之后还有大于70%的堆内存,则系统就会诚少堆的尺寸

-XX:MaxNewSize=size
允许你改变初期对象空间的上限,新建对象所需的内存就是从这个空间中分配来的,这个选项的默认值是640KB (-server选项把默认尺寸增加到2MB)

-XX:MaxPermSize=64m
永 久域(Perm Generation )的大小

-XX:MinHeapFreeRatio=40
修改垃圾回收之后堆中可用内存的最小百分比,默认值是40。如果垃圾回收后至少还有40%的堆内存没有被释放,则系统将增加堆的尺寸

-XX:NewRatio=2
改变新、旧空间的尺寸比例,这个比例的默认值是2,意思是新空间的尺寸是旧空间的1/2

-XX:NewSize=2.125m
为已分配内存的对象中的Eden域设置默认的内存尺寸

-XX:ReservedCodeCacheSize=32m
设置最大的代码缓存的大小

-XX:SurvivorRatio=8
改变Eden 对象空间和残存空间的尺寸比例

-XX:TargetSurvivorRatio=50
设定你所期望的空间提取后被使用的残存空间的百分比

-XX:ThreadStackSize=512
改变线程栈的大小(KB)。在默认情况下,线程栈的大小就是操作系统所使用的栈的默认大小

-XX:+UseBiasedLocking
启用Biase 锁机制

-XX: + UseFastAccessorMethods
使用优化版本

-XX:-UseISM
使用初始化共享内存(IntimateSharedMemory)

-XX:+UseLargePages
使用最大页内存

XX: +UseMPSS
使用多页内存

(3)JVM Debug属性

属性列表及其默认值
述描

-XX:-CITime
显示有多少时间花在编译过的代码上

-XX:ErrorFile= ./hs_err_pid.og
错误发生时保存错误数据到指定的文件中

-XX:-ExtendedDTraceProbes
启用性能跟踪监视器

-XX:HeapDumpPath=-./java_pid.hprof
堆回收的文件路径

-XX :-HeapDumpOnOutOfMemory Error
产生OutOfMemoryError错误时回收堆指定的文件中

-XX:OnError=” cmd args;scmd args>”
产生致命错误时运行用户指定的命令

-XX :OnOutOfMemory Error=”;scmd args”
产生OutOfMemoryError错误时运行用户指定的命令

-XX:-PrintClassHistogram
按下“Ctrl+Break” 组合键时打印类的实例

-XX:-PrintConcurrentLocks
按下“Ctrl+Break” 组合键时打印java.util.concurrent 锁

-XX:-PrintCommandLineFlags
打印命令行的标志属性

-XX:-PrintCompilation
打印Java 方法被编译时的跟踪信息

-XX:-PrinGC
打印垃圾回收信息

-XX:-PrintGCDetails
打印垃圾回收的更多细节

-XX:-PrintGCTimeStamps
打印垃圾回收的时间信息

-XX:-PrintTenuringDistribution
打印初期已分配内存的对象占用内存时间的信息

-XX:-TraceClassLoading
跟踪类的加载

-XX :-TraceClassLoadingPreorder
跟踪所有旧类的加载

-XX:-TraceClassResolution
跟踪常量池

-XX :-TraceClassUnloading
跟踪类的卸载

-XX:-TraceLoaderConstraints
跟踪加载器约束记录

这篇博客讲述一个常用的命令和概念,可以当做以后的指令语法词典来这里搜索回顾,方便以后的JVM调优。

原创粉丝点击