ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# Java–Jvm启动的参数 其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容; 其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容; 其三是非Stable参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用; * 标准参数中比较有用的: ~~~ verbose -verbose:class ~~~ 输出jvm载入类的相关信息,当jvm报告说找不到类或者类冲突时可此进行诊断。 ~~~ -verbose:gc ~~~ 输出每次GC的相关情况。 ~~~ -verbose:jni ~~~ 输出native方法调用的相关情况,一般用于诊断jni调用错误信息。 * 非标准参数又称为扩展参数 一般用到最多的是 \-Xms512m: JVM堆内存初始值为512M。 \-Xmx512m: JVM堆内存最大可用内存为512M。 \-Xmn200m:设置年轻代大小为200M。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小(虚拟机中的共划分为三个代:年轻代(Young Generation)、年老点(Old Generation)和持久代(Permanent Generation)。其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。年轻代和年老代的划分是对垃圾收集影响比较大的。 )。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。 年轻代: 所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。年轻代分三个区。一个Eden区,两个Survivor区(一般而言)。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来 对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。同时,根据程序需要,Survivor区是可以配置为多个的(多于两个),这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。 年老代: 在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。 持久代: 用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。 Scavenge GC 一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。 Full GC 对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个对进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC: · 年老代(Tenured)被写满 · 持久代(Perm)被写满 · System.gc()被显示调用 ·上一次GC之后Heap的各域分配策略动态变化 \-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。 \-Xloggc:file 与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。 若与verbose命令同时出现在命令行中,则以-Xloggc为准。 \-Xprof 跟踪正运行的程序,并将跟踪数据在标准输出输出;适合于开发环境调试。 • 非Stable参数 用-XX作为前缀的参数列表在jvm中可能是不健壮的,SUN也不推荐使用,后续可能会在没有通知的情况下就直接取消了;但是由于这些参数中的确有很多是对我们很有用的,比如我们经常会见到的-XX:PermSize、-XX:MaxPermSize等等; 首先来介绍行为参数: 参数及其默认值 描述 ~~~ -XX:-DisableExplicitGC 禁止调用System.gc();但jvm的gc仍然有效 -XX:+MaxFDLimit 最大化文件描述符的数量限制 -XX:+ScavengeBeforeFullGC 新生代GC优先于Full GC执行 -XX:+UseGCOverheadLimit 在抛出OOM之前限制jvm耗费在GC上的时间比例 -XX:-UseConcMarkSweepGC 对老生代采用并发标记交换算法进行GC -XX:-UseParallelGC 启用并行GC -XX:-UseParallelOldGC 对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用 -XX:-UseSerialGC 启用串行GC -XX:+UseThreadPriorities 启用本地线程优先级 -XX:+ ParallelGCThreads JVM在进行并行GC的时候,用于GC的线程数 ~~~ 上面表格中黑体的三个参数代表着jvm中GC执行的三种方式,即串行、并行、并发; 串行(SerialGC)是jvm的默认GC方式,一般适用于小型应用和单处理器,算法比较简单,GC效率也较高,但可能会给应用带来停顿; 并行(ParallelGC)是指GC运行时,对应用程序运行没有影响,GC和app两者的线程在并发执行,这样可以最大限度不影响app的运行; 并发(ConcMarkSweepGC)是指多个线程并发执行GC,一般适用于多处理器系统中,可以提高GC的效率,但算法复杂,系统消耗较大; 性能调优参数列表: 参数及其默认值 描述 ~~~ -XX:LargePageSizeInBytes=4m 设置用于Java堆的大页面尺寸 -XX:MaxHeapFreeRatio=70 GC后java堆中空闲量占的最大比例 -XX:MaxNewSize=size 新生成对象能占用内存的最大值 -XX:MaxPermSize=64m 老生代对象能占用内存的最大值 -XX:MinHeapFreeRatio=40 GC后java堆中空闲量占的最小比例 -XX:NewRatio=2 新生代内存容量与老生代内存容量的比例 -XX:NewSize=2.125m 新生代对象生成时占用内存的默认值 -XX:ReservedCodeCacheSize=32m 保留代码占用的内存容量 -XX:ThreadStackSize=512 设置线程栈大小,若为0则使用系统默认值 -XX:+UseLargePages 使用大页面内存 -XX:+UseCompressedOops 可以压缩指针,起到节约内存占用的新参数 ~~~ 我们在日常性能调优中基本上都会用到以上黑体的这几个属性; 调试参数列表: 参数及其默认值描述 ~~~ -XX:-CITime 打印消耗在JIT编译的时间 -XX:ErrorFile=./hs_err_pid.log 保存错误日志或者数据到文件中 -XX:-ExtendedDTraceProbes 开启solaris特有的dtrace探针 -XX:- TraceClassUnloading 用来打印类被加载和卸载的过程信息,这个用来诊断应用的内存泄漏问题非常有用 -XX:HeapDumpPath=./java_pid.hprof 指定导出堆信息时的路径或文件名 -XX:-HeapDumpOnOutOfMemoryError 当首次遭遇OOM时导出此时堆中相关信息 -XX:OnError=”;” 出现致命ERROR之后运行自定义命令 -XX:OnOutOfMemoryError=”;” 当首次遭遇OOM时执行自定义命令 -XX:-PrintClassHistogram 遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同 -XX:-PrintConcurrentLocks 遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同 -XX:-PrintCommandLineFlags 打印在命令行中出现过的标记 -XX:-PrintCompilation 当一个方法被编译时打印相关信息 -XX:-PrintGC 每次GC时打印相关信息 -XX:-PrintGCDetails 每次GC时打印详细信息 -XX:-PrintGCTimeStamps 打印每次GC的时间戳 -XX:- PrintGCDateStamps 打印每次GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800) -XX:-TraceClassLoading 跟踪类的加载信息 -XX:-TraceClassLoadingPreorder 跟踪被引用到的所有类的加载信息 -XX:-TraceCla***esolution 跟踪常量池 -XX:-TraceClassUnloading 跟踪类的卸载信息 -XX:-TraceLoaderConstraints 跟踪类加载器约束的相关信息 -XX:- UseGCLogFileRotation 启用GC日志文件的自动转储 -XX:- NumberOfGCLogFiles GC日志文件的循环数目 -XX:- GCLogFileSize 控制GC日志文件的大小 ~~~ * jboss启动配置参数 ~~~ -c, –configuration= Set the server configuration name -b, –host= Bind address for all JBoss services -g, –partition= HA Partition name集群的名称(default=DefaultDomain) -u, –udp= UDP multicast address集群内节点交互的多播地址 -D[=] Set a system property 参数-D设置系统属性jboss.messaging.ServerPeerId的值,JBoss消息需要这个值在群中要求唯一JMX(Java Management Extensions,即Java管理扩展) -Dcom.sun.management.jmxremote.ssl=false ~~~ ~~~ Enable Ssl Connection (True / False)禁止ssl连接-Dcom.sun.management.jmxremote.authenticate=trueconnection authenticate (true / false)开启用户认证-Djava.rmi.server.hostnamemulti eth choose (ip / domain)指定hostname 一般情况需要重新指定hostname,否则连接不成功-Dcom.sun.management.jmxremote.portjmx connection remote port指定hostname 指定端口默认:1099-Dcom.sun.management.jmxremote.access.fileremote access roles (file path)访问模式-Dcom.sun.management.jmxremote.password.fileremote authenticate file when authenticate enable (file path)认证用户名密码 ~~~ 注意:jmxremote.password和jmxremote.access文件只允许启动用户名对该文件拥有读写权限,我们服务用appsup启动 所以: ~~~ [appsup@ukoclntrtap01u ~]$ ll /usr/java/default/jre/lib/management/ total 28 -rw-r–r–. 1 appsup users 3998 Dec 19 2014 jmxremote.access -rw——-. 1 appsup users 2854 Jun 13 11:18 jmxremote.password ~~~ 如果权限设置不正确会报错:Error: Password file read access must be restricted ~~~ -Djava.endorsed.dirs ~~~ 可以简单理解为-Djava.endorsed.dirs指定的目录里面放置jar文件,将有覆盖系统API的功能。可以牵强的理解为,将自己修改后的API打入到虚拟机指定的启动API中,取而代之。但是能够覆盖的类是有限制的,其中不包括java.lang包中的类 ~~~ -classpath ~~~ 参数为目录下所有jar文件 ~~~ -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 ~~~ 指定rmi调用时gc的时间间隔 rmi是Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI全部的宗旨就是尽可能简化远程接口对象的使用。 \-Djava.awt.headless=true Headless模式是系统的一种配置模式。在该模式下,系统缺少了显示设备、键盘或鼠标。 ~~~ -Dsun.lang.ClassLoader.allowArraySyntax=true ~~~ (This property is needed to workaround for the bug 6434149 for JAVA 1.6 ) as it won’t work without it. 原来jdk5.0的时候不会报这个错java.lang.ClassNotFoundException: \[Ljava.lang.String,用了jdk6.0就出现了这个错误,因为没有重载java.lang.String这个类 ~~~ -Doracle.net.tns_admin ~~~ 设置JVM的oracle.net.tns\_admin的system property Oracle中TNS的完整定义:transparence Network Substrate透明网络底层,监听服务是它重要的一部分,不是全部,不要把TNS当作只是监听器。 TNS是Oracle Net的一部分,专门用来管理和配置Oracle数据库和客户端连接的一个工具,在大多数情况下客户端和数据库要通讯,必须配置TNS,当然在少数情况下,不用配置TNS也可以连接Oracle数据库,比如通过JDBC。如果通过TNS连接Oracle,那么客户端必须安装Oracle client程序。 Oracle当中,如果想访问某个服务器,必须要设置TNS,它不像SQL SERVER那样在客户端自动列举出在局域网内所有的在线服务器,只需在客户端选择需要的服务器,然后使用帐号与密码登录即可。而Oracle不能自动列举出网内的服务器,需要通过读取TNS配置文件才能列出经过配置的服务器名。 ~~~ 配置文件名一般为:tnsnames.ora,默认路径:%ORACLE_HOME%\network\admin\tnsnames.ora -java.net.preferIPv4Stack (default: false)If IPv6 is available on the operating system the underlying native socketwill be an IPv6 socket. This allows Java(tm) applications to connect too, and accept connections from, both IPv4 and IPv6 hosts. If an application has a preference to only use IPv4 sockets then this property can be set to true. The implication is that the application will not be able to communicate with IPv6 hosts. -Djboss.platform.mbeanserver 让JBoss EAP 使用jdk的mbean server MBean通常是一个java类,它提供接口可以使这个类具有管理功能(如standard MBean,接口中定义的方法使MBean具有管理功能)。 MBeanServer是管理MBean的一个java类,你需要向MBean server注册一个MBean后,这个MBean才会具有管理功能,MBean server还提供了查询功能和注册监听器的功能,sun提供的只是接口,不同的jmx实现中的MBean server实现也不同。 MBeanServer是一个包含所有注册MBean的仓库.它是JMX代理层的核心.JMX1.0规范提供一个接口叫 javax.management.MBeanServer. 所有管理的在MBean操作通过MBeanServer执行.使用MBeanServer实例,你能够管理所有MBean.每一个MBean具有一个唯一标志,叫ObjectName. -Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl 如果是jboss 4.x,在jvm启动参数中加入-Djboss.platform.mbeanserver就可以了.对于jboss eap 5.x,由于其基于jboss as 5.1,还需要这个参数-Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl否则启动就报一堆异常。 ~~~ ~~~ -javaagent:/opt/appoptics/appoptics-agent.jar ~~~ 会在main方法之前预先执行premain方法 Agent 类必须打成jar包,然后里面的 META-INF/MAINIFEST.MF 必须包含 Premain-Class这个属性 ~~~ -Dorg.jboss.resolver.warning=true This option warns when an XML entity is defined as SYSTEM with protocol is not “file://” or “vfsfile://”, which is most likely something not expected. -org.jboss.Main ~~~ run.sh中的参数org.jboss.Main ~~~ -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n -Xrunjdwp ~~~ This option loads the JPDA reference implementation of JDWP. This library resides in the target VM and uses JVMDI and JNI to interact with it. It uses a transport and the JDWP protocol to communicate with a separate debugger application. ~~~ dt_socket:使用的通信方式 server:是主动连接调试器还是作为服务器等待调试器连接 suspend:是否在启动JVM时就暂停,并等待调试器连接 address:地址和端口,地址可以省略,两者用冒号分隔 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005JVM 1.5以后的版本应该使用类似上面的命令(老的还是可以使用的),就是一个agentlib就行了,后面的参数都没有变 ~~~ ~~~ -Djboss.modules.system.pkgs=org.jboss.byteman ~~~ This complicates matters for integration with other javaagents which alter the script because this property must also be set and it is not defined in the JVM what precedence is given to multiple same property settings on the command line. ~~~ -Djboss.modules.policy-permissions=true ~~~ The Java Security Manager must be enabled for the JBoss application server. ~~~ -jaxpmodule javax.xml.jaxp-provider org.jboss.as.standalone ~~~ JAXP(Java API for XMLProcessing,意为XML处理的Java API)是Java XML程序设计的应用程序接口之一,它提供解析和验证XML文档的能力。 ~~~ -Djruby.native.enabled=false ~~~ 关闭Ruby ~~~ -Djava.library.path=/bin/native ~~~ 指定非java类包的位置(如:dll,so) \[参考链接\] [https://blog.csdn.net/normanjin/article/details/82384037](https://blog.csdn.net/normanjin/article/details/82384037)