jvm调优-笔记

参照:java程序性能优化 让你的java程序更快更稳定.pdf

一、java虚拟机内存模型

java虚拟机内存模型是Java程序运行的基础。为了能使Java应用程序正常运行,JVM虚拟机将其内存结构分为程序计数器、虚拟机栈、本地方法栈、Java堆,方法区


程序计数器用于存放下一条运行的指令;虚拟机栈和本地方法栈用于存放函数调用堆栈信息;java堆用于存放Java程序运行时候所需的对象等数据;方法区用于存放程序的类元素等信息。

1、程序计数器

程序计数器是一块很小的内存空间。每个线程都必须有一个独立的程序计数器,用于记录下一条要运行的命令。各个线程之间的计数器互不影响,独立工作,是一块线程的私有变量,如果当前线程正在执行一个java方法,则程序计数器记录正在执行的java字节码地址,如果当前正在执行一个native方法,则程序计数器为空。

2、java虚拟机栈

java虚拟机栈也是线程私有的内存空间,它和java线程在同一时间创建,它保存方法的局部变量、部分结果,并参与方法的返回和调用。

java虚拟机规范允许Java栈的大小是动态或者是固定的。在java虚拟机规范中,定义了两种异常和其相关:StackOverflowError和OutOfMemoryError。如果线程在计算中,请求的栈深度大于最大可用的栈深度,则抛出StackOverflowError;如果java栈可以动态扩展,而在扩展过程中没有足够的内存空间支持其扩展,则抛出OutOfMemoryError。

可以使用 -Xss参数设置栈的大小。

3、本地方法栈

本地方法栈和java虚拟机栈的功能相似,java虚拟机栈用于管理java函数的调用,而本地方法栈用于管理本地方法的调用。本地方法并不是用java实现的,而是用c实现的,在sun的Hot Spot虚拟机中,不区分本地方法栈和虚拟机栈。

4、java堆

java堆分成新生代和老年代两个部分,新生代用于存放刚刚产生的对象和年轻的对象,如果对象一直没有被回收,生存的足够长,就会被移入到老年代。

5、方法区

方法区也是JVM内存区中的非常重要的一块内存区域,与堆空间类似,它也是jvm中所有的线程功效的。方法区中主要保存的信息是类的元数据。

方法区中最为重要的是类的类型信息、常量池、域信息、方法信息。

类型信息包括类的完整名称,父类的完整名称、类型修饰符和类的直接接口;

常量池包括这个类的方法、域等信息所引用的常量信息;

域信息包括域名称、域类型和域修饰符;

方法信息包括方法名称、返回类型、方法参数、方法修饰符、方法字节码、操作数栈和方法帧栈的局部变量区大小以及异常表。

在Hot Spot虚拟机中,方法区也称为永久区,是一块独立于java堆的内存空间

二、JVM内存分配参数

java应用程序可以使用的最大堆可以使用-Xmx参数设定。最大堆是指新生代和老年代的大小之和的最大值。

使用-Xms可以用于设置系统最小堆空间。也就是JVM启动时候所占据的操作系统内存大小。

参数-Xmn用于设置新生代的大小,新生代的大小一般设置为整个堆空间的1/4到1/3左右。

持久代(方法区)不属于堆的一部分。使用-XX:MaxPermSize可以设置持久代最大值,-XX:PermSize可以设置持久代的初始大小。

设置线程栈可以使用-Xss参数设置线程栈的大小。

三、垃圾回收算法与思想

1、引用计数法

引用计数法实现比较简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器就减一,只要对象A的引用计数器为0,则对象A就不可能被在使用,弊端:无法处理循环引用:如有对象A和B,A中含有B的引用,B中含有A的引用,此时A和B的引用计数器都不为0,但系统却不存在任何第三个对象引用了A和B,也就是说A和B应该被回收,但由于对象间的相互引用,从而使垃圾回收器无法识别,引起内存泄露。

2、标记-清除算法

3、复制算法

4、标记压缩算法

5、增量算法

6、分代

四、常用调优案例和算法

1、新生代的垃圾回收速度高于老年代回收,因此,将年轻对象预留在新生代有利于提高整体的GC效率。

2、稳定的堆大小对垃圾回收有利,获得一个稳定的堆大小的方法是使-Xms和-Xmx的大小一致,如果这样设置,系统在运行时候堆大小是恒定的,稳定的堆空间可以减少GC的次数。

五、实战JVM调优

使用startup.bat启动tomcat服务器,startup.bat调用了bin目录下的catalina.bat文件,如果需要配置tomcat的JVM参数,可以将参数写入catalina.bat中。

catalina.bat中有两项均可以设置JVM的优化参数:CATALINA_OPTS或者JAVA_OPTS

根据说明的建议,类似于堆大小、GC日志和JMX端口等推荐配置在CATALINA_OPTS中,为了获取tomcat启动的GC信息,可在catalina.bat中加入:

set CATALINA_OPTS=-Xloggc:gc.log -XX: +PrintGCDetails

JVM调优的主要过程有:确定堆内存大小(-Xmx、_Xms)、合理分配新生代和老年代(-XX:NewRatio、Xmn、-XX:SurvivorRatio)、确定永久区大小(-XX:Permsize、-XX:MaxPermsize)、选择垃圾收集器、对垃圾收集器进行合理的设置。除此之外,禁用显示GC(-XX:+DisableExplicitGC),禁用类元数据回收(-Xnoclassgc),禁用类验证(-Xverify:none)等设置,对提升系统性能也有一定的帮助

六、Java性能调优工具

相关文章