Java虚拟机深入理解系列全部文章更新中...

  • https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-java-nei-cun-qu-yu-tou-che-fen-xi.html
  • https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-chang-yong-vm-can-shu-fen-xi.html
  • https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-jvm-nei-cun-fen-pei-yu-hui-shou-ce-lue-yuan-li-cong-ci-gao-bie-jvm-nei-cun-fen-pei-wen-mang.html
  • https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-ru-he-li-yong-jdk-zi-dai-de-ming-ling-xing-gong-ju-jian-kong-shang-bai-wan-de-gao-bing-fa-de-xu-ni-ji-xing-neng.html
  • https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-ru-he-li-yong-visualvm-dui-gao-bing-fa-xiang-mu-jin-xing-xing-neng-fen-xi.html
  • https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-ni-liao-jie-gc-suan-fa-yuan-li-ma.html

话不多说,今天就分析一下一些常用的Java虚拟机的参数设置,以及如何更好的使用!

1 JVM参数简介

首先想说的是其实这些参数我们并不是陌生的,在平时的开发和使用中经常都会遇到,只是在平时缺少一个比较系统的总结,所以,对这些参数感觉是很陌生的,所以,通过这篇文章的总结,我相信你一定都会对这些参数熟稔于心,做做心中有数。

在Java虚拟机的参数中,其实可以把这些参数分为三类,当然,这是针对JDK1.6来说的,如果对于JDK1.8,那么就不是这么分类的了,但是,由于这两个版本很多常用的参数的差别是不大的,所以这篇文章就先介绍JDK1.6的VM参数。

主要可以分为以下三类:

  • 标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容。
  • 非标准参数(-X),默认JVM实现这些参数的功能,但是并不保证所有JVM实现都满足,且不保证向后兼容。
  • 非Stable参数(-XX),此类参数各个JVM实现会有所不同,将来可能会随时取消,需要慎重使用。

虽然是这么分类的,实际上呢,非标准参数和非稳定的参数实际的使用中还是用的非常的多的,在后面的文章的介绍中你就会发现。

2 标准参数

这一类参数可以说是我们刚刚开始Java是就用的非常多的参数了,比如java -version、java -jar等等,我们在CMD中输入java -help就可以获得Java当前版本的所有标准参数了。

如上图就是JDK1.8的所有标准参数了,下面我们将介绍一些我们会用的比较多的参数。

  • -client

以client模式启动JVM,这种方式启动速度快,但运行时性能和内存管理效率不高,适合客户端程序或者开发调试。

  • -server

以server模式启动JVM,与client情况恰好相反。适合生产环境,适用于服务器。64位的JVM自动以server模式启动。

  • -classpath或者-cp

通知JVM类搜索路径。如果指定了-classpath,则JVM就忽略CLASSPATH中指定的路径。各路径之间以分号隔开。如果-classpath和CLASSPATH都没有指定,则JVM从当前路径寻找class。

JVM搜索路径的顺序:

1.先搜索JVM自带的jar或zip包。

Bootstrap,搜索路径可以用System.getProperty("sun.boot.class.path")获得;

2.搜索JRE_HOME/lib/ext下的jar包。

Extension,搜索路径可以用System.getProperty("java.ext.dirs")获得;

3.搜索用户自定义目录,顺序为:当前目录(.),CLASSPATH,-cp。

搜索路径用System.getProperty("java.class.path")获得。

System.out.println(System.getProperty("sun.boot.class.path"));System.out.println(System.getProperty("java.ext.dirs"));System.out.println(System.getProperty("java.class.path"));

如上就是我电脑的JVM的路径。

  • -DpropertyName=value

定义系统的全局属性值,如配置文件地址等,如果value有空格,则需要使用双引号。

另外用System.getProperty("hello")可以获得这些定义的属性值,在代码中也可以用System.setProperty("hello","world")的形式来定义属性。

如键值对设置为hello=world。

System.out.println(System.getProperty("hello"));

运行结果就是:

  • -verbose

查询GC问题最常用的命令之一,参数如下:-verbose:class输出JVM载入类的相关信息,当JVM报告说找不到类或者类冲突时可此进行诊断。-verbose:gc输出每次GC的相关情况。-verbose:jni输出native方法调用的相关情况,一般用于诊断jni调用错误信息。

另外,控制台输出GC信息还可以使用如下命令:

在JVM的启动参数中加入-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime,按照参数的顺序分别输出GC的简要信息,GC的详细信息、GC的时间信息及GC造成的应用暂停的时间。

3 非标准参数

非标注的参数主要是关于Java内存区域的设置参数,所以在看这些参数之前,应该先查看Java内存区域的基础知识,可以查看这篇文章:https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-java-nei-cun-qu-yu-tou-che-fen-xi.html。

非标准参数实在标准参数的基础上的一些扩充参数,可以输入java -X,获得当前JVM支持的非标准参数。

从图片中可以看出来,这些非标准的参数其实不多的,下面我们再 讲解一些比较常用的参数。

  • -Xmn

新生代内存大小的最大值,包括E区和两个S区的总和。设置方法:-Xmn512m、-Xmn2g。

  • -Xms

初始堆的大小,也是堆大小的最小值,默认值是总共的物理内存/64(且小于1G)。默认情况下,当堆中可用内存小于40%,堆内存会开始增加,一直增加到-Xmx的大小。

  • -Xmx

堆的最大值,默认值是总共的物理内存/64(且小于1G),默认情况下,当堆中可用内存大于70%,堆内存会开始减少,一直减小到-Xms的大小。

因此,为了避免这种浮动,所以在设置-Xms和-Xmx参数时,一般会设置成一样的,能够提高性能。

另外,官方默认的配置为年老代大小:年轻代大小=2:1左右,使用-XX:NewRatio可以设置年老代和年轻代之比,例如,-XX:NewRatio=4,表示年老代:年轻代=4:1

参数实例

设置-Xms、-Xmn和-Xmx参数分别为-Xms512m -Xmx512m -Xmn128m。同时设置新生代和老生代之比为1:4,E:S0:S1=8:1:1。

** * @ClassName MethodTest * @Description vm参数设置:-Xms512m -Xmx512m -Xmn128m -XX:NewRatio=4 -XX:SurvivorRatio=8  * @Author 欧阳思海 * @Date 2019/11/25 20:06 * @Version 1.0 **/public class MethodTest { public static void main(String[] args) { List list = new ArrayList(); long i = 0; while (i < 1000000000) { System.out.println(i); list.add(String.valueOf(i++).intern()); } }}

运行之后,用VisualVM查看相关信息是否正确。

当我们没有设置-XX:NewRatio=4 -XX:SurvivorRatio=8时,使用官方默认的情况如下:

上图可以看出,新生代(Eden Space + Survivor 0 + Survivor 1):老年代(Old Gen)≈ 1:2

当我们设置了-XX:NewRatio=4 -XX:SurvivorRatio=8时,情况如下:

变成了新生代(Eden Space + Survivor 0 + Survivor 1):老年代(Old Gen)≈ 1:4,Eden Space:Survivor 0: Survivor 1 = 8:1:1。

从上图可知,堆的信息是正确的。

  • -Xss

设置每个线程的栈内存,默认1M,一般来说是不需要改的。

  • -Xprof

跟踪正运行的程序,并将跟踪数据在标准输出输出;适合于开发环境调试。

  • -Xnoclassgc

禁用类垃圾收集,关闭针对class的gc功能;因为其阻止内存回收,所以可能会导致OutOfMemoryError错误,慎用。

  • -Xincgc

开启增量gc(默认为关闭);这有助于减少长时间GC时应用程序出现的停顿;但由于可能和应用程序并发执行,所以会降低CPU对应用的处理能力。

  • -Xloggc:file

与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。若与verbose命令同时出现在命令行中,则以-Xloggc为准。

  • -Xint

在解释模式(interpreted mode)下,-Xint标记会强制JVM执行所有的字节码,这会降低运行速度,通常低10倍或更多。

  • -Xcomp

-Xcomp参数与它(-Xint)正好相反,JVM在第一次使用时会把所有的字节码编译成本地代码,从而带来最大程度的优化。

然而,很多应用在使用-Xcomp也会有一些性能损失,当然这比使用-Xint损失的少,原因是-xcomp没有让JVM启用JIT编译器的全部功能。JIT编译器可以对是否需要编译做判断,如果所有代码都进行编译的话,对于一些只执行一次的代码就没有意义了。

  • -Xmixed

-Xmixed是混合模式,这是JVM默认的模式,也是推荐使用的模式。将解释模式与编译模式进行混合使用,由JVM自己决定。

4 非Stable参数

这类参数你一看官网以为不能使用呢,官网给你的建议就是这些参数不稳定,慎用,其实这主要的原因还是因为每个公司的实现都是不一样的,所以就是导致不稳定。但是呢,在实际的使用中却是非常的多的,而且这部分的参数很重要。

这些参数大致可以分为三类:

  • 性能参数(Performance Options):用于JVM的性能调优和内存分配控制,如初始化内存大小的设置;
  • 行为参数(Behavioral Options):用于改变JVM的基础行为,如GC的方式和算法的选择;
  • 调试参数(Debugging Options):用于监控、打印、输出等jvm参数,用于显示jvm更加详细的信息;

下面还是先罗列一些比较常用的参数,其实,这些文章很多了,这里主要还是做一个总结,以后自己看文章的时候比较方便,如果有同行看到了文章,你可以参考参考,还是很有帮助的。

另外,选取其中的一些参数做一些例子来解释,这样也能够更加的形象。

注意:以下参数都是JDK1.7及以下可以使用。

  • 性能参数

参数及其默认值 描述 -XX:LargePageSizeInBytes=4m
设置用于Java堆的大页面尺寸 -XX:MaxHeapFreeRatio=70
GC后java堆中空闲量占的最大比例 -XX:MinHeapFreeRatio=40 GC后java堆中空闲量占的最小比例 -XX:MaxNewSize=size 新生成对象能占用内存的最大值 -XX:MaxPermSize=64m
老生代对象能占用内存的最大值 -XX:NewRatio=2
新生代内存容量与老生代内存容量的比例 -XX:NewSize=2.125m 新生代对象生成时占用内存的默认值 -XX:ReservedCodeCacheSize=32m
保留代码占用的内存容量 -XX:ThreadStackSize=512
设置线程栈大小,若为0则使用系统默认值 -XX:+UseLargePages
使用大页面内存

  • 行为参数

参数及其默认值
描述 -XX:+ScavengeBeforeFullGC
新生代GC优先于Full GC执行 -XX:+UseGCOverheadLimit
在抛出OOM之前限制jvm耗费在GC上的时间比例 -XX:-UseParNewGC 打开此开关,使用ParNew+Serial Old收集器 -XX:-UseConcMarkSweepGC
使用ParNew+CMS+Serial Old收集器对老生代采用并发标记交换算法进行GC -XX:-UseParallelGC
启用并行GC,使用ParallelScavenge+Serial Old收集器 -XX:-UseParallelOldGC
对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用,ParallelScavenge+Parallel Old收集器 -XX:-UseSerialGC
启用串行GC -XX:+UseG1GC 使用垃圾优先(G1)收集器 -XX:SurvivorRatio=n
Eden区域与Survivor区域大小之比。预设值为8 -XX:PretenureSizeThreshold=n 直接晋升到老年代的对象大小,设置这个参数之后,大于这个参数的对象直接进入到老年代分配 -XX:MaxTenuringThreshold=n 晋升到老年代的对象年龄,每个对象在坚持过一次Minor GC之后,年龄加1,当超过这个值之后就进入老年代。预设值为15 -XX:+UseAdaptiveSizePolicy 动态调整Java堆中各个区域的大小以及进入老年代的年龄 -XX:ParallelGCThreads=n 设置并行收集器收集时使用的CPU数。并行收集线程数 -XX:MaxGCPauseMillis=n 设置并行收集最大暂停时间 -XX:GCTimeRatio=n 设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+N) -XX:+UseThreadPriorities
启用本地线程优先级 -XX:-DisableExplicitGC
禁止调用System.gc();但jvm的gc仍然有效 -XX:+MaxFDLimit
最大化文件描述符的数量限制

前面6个参数都是关于垃圾收集器的行为参数,也是经常会用到的参数。

  • 调试参数

参数及其默认值 描述 -XX:-CITime 打印消耗在JIT编译的时间 -XX:ErrorFile=./hserrpid .log
保存错误日志或者数据到文件中 -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:-TraceClassLoading
跟踪类的加载信息 -XX:-TraceClassLoadingPreorder
跟踪被引用到的所有类的加载信息 -XX:-TraceClassResolution 跟踪常量池 -XX:-TraceClassUnloading 跟踪类的卸载信息 -XX:-TraceLoaderConstraints 跟踪类加载器约束的相关信息

5 JDK8的VM参数

由于考虑到现在JDK8用的非常的广泛,所以,接下来总结一些JDK8会使用到的参数。

查看这篇https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html你会发现,标准参数和非标准参数JDK8的差别并不是很大,如果有其他的参数需要使用,可以查看上面这篇文章。

深入java虚拟机 第四版_深入理解Java虚拟机-常用vm参数分析相关推荐

  1. 深入jvm虚拟机第4版_深入理解JVM虚拟机

    自动内存管理机制 Java虚拟机原理 所谓虚拟机,就是一台虚拟的机器.他是一款软件,用来执行一系列虚拟计算指令,大体上虚拟机可以分为 系统虚拟机和程序虚拟机, 大名鼎鼎的Visual Box.Vmar ...

  2. 深入理解Java虚拟机-常用vm参数分析

    Java虚拟机深入理解系列全部文章更新中- 深入理解Java虚拟机-Java内存区域透彻分析 深入理解Java虚拟机-常用vm参数分析 深入理解Java虚拟机-JVM内存分配与回收策略原理,从此告别J ...

  3. java jvm垃圾回收算法_深入理解JVM虚拟机2:JVM垃圾回收基本原理和算法

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 喜欢的话麻烦点下Star哈 文章将同步到我的个人博客: www.how ...

  4. 深入理解java虚拟机 - jvm高级特性与最佳实践(第三版)_深入理解Java虚拟机,JVM高级特性与最佳实践!...

    第一部分 走进Java 第二部分 自动内存管理机制 第三部分 虚拟机执行子系统 参考资料: 书籍,网站资源 Java不仅仅是一门编程语言,还是一个由一系列计算机软件和规范形成的技术体系,这个技术体系提 ...

  5. java中对象的生存期_深入理解Java虚拟机-判断对象是否存活算法与对象引用

    我们知道Java中的对象一般存放在堆中,但是总不能让这些对象一直占着内存空间,这些对象最终都会被回收并释放内存,那么我们如何判断对象已经成为垃圾呢?这篇文章会提出两种算法解决这个问题.另外,本文还要谈 ...

  6. java方法区内存泄露_深入理解java虚拟机-第二章:java内存区域与内存泄露异常...

    2.1概述: java将内存的管理(主要是回收工作),交由jvm管理,确实很省事,但是一点jvm因内存出现问题,排查起来将会很困难,为了能够成为独当一面的大牛呢,自然要了解vm是怎么去使用内存的. 2 ...

  7. java虚拟机的生命周期_深入理解Java虚拟机——JVM的生命周期

    package test; public class JVMTestLife { public static void main(String[] args) { new Thread(new Run ...

  8. 深入理解 Java 虚拟机(第二弹) - 常用 vm 参数分析

    来自:好好学java 话不多说,今天就分析一下一些常用的Java虚拟机的参数设置,以及如何更好的使用! 1 JVM参数简介 首先想说的是其实这些参数我们并不是陌生的,在平时的开发和使用中经常都会遇到, ...

  9. java if在内存中_全面理解Java内存模型

    Java 内存模型的抽象 在 java 中,所有实例域.静态域和数组元素存储在堆内存中,堆内存在线程之间共享(本文使用"共享变量"这个术语代指实例域,静态域和数组元素).局部变量( ...

最新文章

  1. WinCE的C#编程,对float型进行四舍五入保留两位小数,小数进行四舍五入操作,Math.Round的应用案例。...
  2. Demo学习: CalendarPanel
  3. mysql两张表一起计数_mysql-同一张表上的多个联接,其中一个查询计数
  4. python基础list_python基础之List详解
  5. fiber报错 (type *big.Int has no field or method FillBytes)
  6. MiniO对象存储服务 磁盘缓存快速入门 ​​​​​​​
  7. 【王道考研计算机网络】—分层结构 协议 接口 服务
  8. C++对象产生和销毁的顺序
  9. DotCMS安装步骤
  10. 克隆卡设备_SD Clone for mac(SD卡克隆备份软件) v3.2
  11. proguard 反编译_Android Studio项目结构,编译器,ProGuard
  12. CentOS7系统中:安装tree命令的问题
  13. ERP原理与应用教程-第一章
  14. 采用计算机对酒店客房进行管理,酒店客房管理系统—计算机毕业设计论文.doc...
  15. EXCEL----数据处理(二)----B列中包含了A列的项
  16. 美式期权定价python_蒙特卡洛模拟和美式期权定价
  17. 华为机试-拼音翻译成阿拉伯数字
  18. ppt怎么转pdf?经验分享
  19. CSS媒体类型基本知识
  20. 基于Linux系统的KingbaseES数据库软件安装指南(3. 安装前准备工作)

热门文章

  1. 套娃成功!在《我的世界》里运行Win95、玩游戏,软件和教程现已公开
  2. Jupyter 官方神器:可视化 Debug 工具!
  3. 谷歌大脑联手Hinton提出SimCLR新框架,疯狂提升自监督学习性能 | 北邮毕业生一作...
  4. 身边的隐形富豪,都有哪些特征?
  5. 模板引擎-模板引擎渐进进化
  6. 在各种xDSL技术中,能提供上下行信道非对称传输的是______。正确答案 B
  7. ACMNO.40 C语言-子串 有一字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串
  8. 2022 年计算机视觉的三大趋势
  9. 一个雷达和摄像头融合的3D目标检测方法CenterFusion
  10. 服务器处理 json 数据