JVM内存分配方式

Reading time ~7 minutes

此文章为原创文章,引用请标记文章出处: JVM内存分配方式

概述

java性能优化的步骤通常是先进行操作系统性能监控、JVM性能监控、性能分析后找到影响性能的原因,然后可能对诸如:HotSpot VM、JVM垃圾收集器、操作系统或应用程序的调优。本文只讨论常见的JVM内存分配方式,其余的以后有机会再总结。

术语

  • 堆(Heap)和非堆(Non-heap)内存

Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在Java虚拟机启动时创建的。在JVM中堆之外的内存称为非堆内存(Non-heapmemory)。

可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。

  • JVM内存限制(最大值)

首先JVM内存首先受限于实际的最大物理内存,假设物理内存无限 大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是 2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了

内存调配方式

出现调整JVM内存的场景最常见的莫过于OutOfMemoryError,出现这个错误通常的解决方法就是加大分配JVM堆内存

1.对于本地的程序

可以使用命令对运行时的jvm内存进行设置

java -Xms64m -Xmx256m Test

-Xms是设置内存初始化的大小

-Xmx是设置最大能够使用内存的大小(最好不要超过物理内存大小)

2.对于使用Eclipse运行的程序

可以在Eclipse安装目录下的eclipse.ini分配内存,eclipse.ini文件的内容要按照格式编写。

-vmargs
-Xms128M
-Xmx512M
-XX:PermSize=64M
-XX:MaxPermSize=128M

1.参数中-vmargs的意思是设置JVM参数,所以后面的其实都是JVM的参数

2.JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小

3.-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

4.-XX:+UseParallelGC 在双核的CPU下让GC可以更快的执行

3.在应用服务器下的应用

根据不同的服务器在不同的配置文件下配置内存,以下主要讲Tomcat和Weblogic中的配置

3.1 Tomcat

在TOMCAT的目录下,也就是在TOMCAT安装目录/bin/catalina.bat文件最前面加入:

set JAVA_OPTS=-Xms800m -Xmx800m

根据以上配置,当你重新启动TOMCAT时,系统内存会增加近800M使用

3.2 Weblogic

可以在startweblogic.cmd中或者在/bin/setDomainEnv.cmd文件对每个domain虚拟内存的大小进行设置,而所有domain的默认的内存大小是在commom\bin\commEnv.cmd里面配置的,以下是commEnv.cmd里主要的JVM内存配置的代码片段:

:bea
if "%PRODUCTION_MODE%" == "true" goto bea_prod_mode

set JAVA_VM=-jrockit //使用的是Weblogic提供的jrockit作为JDK

set MEM_ARGS=-Xms768m -Xmx1024m -XX:MaxPermSize=256m

set JAVA_OPTIONS=%JAVA_OPTIONS% -Xverify:none

goto continue

:bea_prod_mode

set JAVA_VM=-jrockit

set MEM_ARGS=-Xms768m -Xmx1024m -XX:MaxPermSize=256m//调整后和把上面的MEM_ARGS也配置成一样

goto continue

以下是startweblogic.cmd文件的配置:

set DOMAIN_HOME=E:\Weblogic\Middleware\user_projects\domains\base_domain
set USER_MEM_ARGS=-XX:PermSize=256m  -XX:MaxPermSize=256m -Xms800m -Xmx800m
call "%DOMAIN_HOME%\bin\startweblogic.cmd" %*

以下是setDomainEnv.cmd文件的配置: 主要就是修改-Xms、-Xmx、-XX:PermSize、-XX:MaxPermSize的参数(视具体硬件、JVM负载情况进行修改)。如果需要设置-Xss等其它相关参数,也可添加到最后的MEM_ARGS中。

这里需要注意的是有个32位、64位的区别。实际上具体采用哪种配置,可查看文件, 如:

Weblogic11\wlserver_10.3\common\bin\commEnv.cmd 找到set JAVA_USE_64BIT=false配置,即表示非64位环境。

setDomainEnv.cmd文件的配置

实践

1.选择高版本的jdk,因为高版本的自动调优方式可以极大改善性能。

2.Weblogic有两种JDK供选择,一种是Sun的JDK,另外一种是Bea的jrockit。作为Weblogic集群推荐采用jrockit作为JDK环境,来达到更高的性能。

3.部署应用时将JVM换成Server的模式会提升很大性能,但在启动时会比Client模式慢。32位的虚拟机在目录JAVA_HOME/jre/lib/i386/jvm.cfg,64位的在JAVA_HOME/jre/lib/amd64/jvm.cfg,目前64位只支持server模式

-server KNOWN
-client KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR

一般只要变更 -server KNOWN 与 -client KNOWN 两个配置位置先后顺序即可,前提是JAVA_HOME/jre/bin 目录下同时存在 server 与client两个文件夹,分别对应着各自的jvm.如果缺少其中一个,切换模式时就会报错。

参考资料

1.Weblogic11g-常用运维操作

2.JVM内存原理,weblogic内存的调优

3.Eclipse中进行JVM内存设置

jdk-timer、spring-task、quartz的比较

这篇文章将简单介绍目前常用的定时任务框架! Continue reading

小岛经济学-读书笔记

Published on May 10, 2018

java常见的http请求库

Published on May 05, 2018