一、跟踪调试参数

1.1 跟踪垃圾回收-读懂虚拟机日志

Java的一大特色就是支持自动的垃圾回收(GC),但是有时候,如果垃圾回收频繁出现,或者占用了太长的CPU时间,就不得不引起重视。此时,就需要一些跟踪参数来进一步甄别垃圾回收器的效率和效果。

最简单的一个GC参数是-XX:+PrintGC,使用这个参数启动Java虚拟机后,只要遇到GC,就会打印日志。

如果需要更加详细的信息,则可以使用-XX:+PrintGCDetails参数。他的输出可能如下:

从这个输出可以看到,系统经历了3次GC,第一次仅为新生代GC,回收的效果是新生代从回收前的8MB左右降到了1M左右。整个堆从22MB左右降到了17MB。

第二次为Full GC,它同时回收了新生代、老年代和永久区。从日志显示,新生代在这次GC中没有释放空间(严格来说,这是GC日志的一个小bug,事实上,在这次Full GC完成后,新生代被清空,由于GC日志输出时机的关系,各个版本的JDK日志多少有些不太精确的地方),老年代从16MB降到了13MB。整个堆大小从26MB左右降到了13MB左右(这个大小完全与老年代实际大小相等,因此可以推断,新生代实际上已被清空)。永久区的大小没有变化。日志的最后,显示了GC花费的时间,其中user表示用户态CPU耗时,sys表示系统CPU耗时,real表示GC实际经历的时间。

如果需要更全面的堆信息,还可以使用参数-XX:+PrintHeapAtGC。他会在每次GC前后分别打印堆的信息。

如果需要分析GC发生的时间,还可以使用-XX:+PrintGCTimeStamps参数,该参数会在每次GC发生时,额外输出GC发生的时间,该输出时机为虚拟机启动后的时间偏移量。

默认情况下,GC的日志会在控制台输出,这不便于后续分析和定位问题。为此,虚拟机允许将GC日志以文件的形式输出,可以使用参数-Xloggc指定。

1.2 类加载/卸载的跟踪

一般情况下,系统加载的类存在于文件系统中,以jar的形式打包或者以class文件的形式存在,可以直接通过文件系统查看。但是随着动态代理、AOP等技术的普遍使用,系统也ji'ke'neng极可能在运行时动态生成某些类,这些类相对比较隐蔽,无法通过文件系统找到。

可以使用参数-verbose:class跟踪类的加载和卸载,也可以单独使用参数-XX:+TraceClassLoading跟踪类的加载,使用参数-XX:+TraceClassUnloading跟踪类的卸载。

Java虚拟机还允许研发人员在运行时打印、查看系统中类的分布情况,只要在系统启动时加上-XX:+PrintClassHistogram参数,然后在Java控制台按下Ctrl+Break组合键,控制台就会显示当前的类信息柱状图。

1.3 系统参数查看

参数-XX:+PrintVMOptions可以在程序运行时,打印虚拟机接收到的命令行显式参数。

参数-XX:+PrintCommandLineFlags可以打印传递给虚拟机的显式和隐式参数。

二、学习堆的配置参数

2.1 最大堆和初始堆的设置

  • Xms:初始堆
  • Xmx:最大堆

在实际工作中,也可以直接将初始堆-Xms和最大堆-Xmx设置相等,这样好处是可以减少程序运行时进行的垃圾回收次数,从而提高程序的性能。

2.2 新生代的配置

参数-Xmn可以用于设置新生代的大小。设置一个较大的新生代会减小老年代的大小,这个参数对系统性能以及GC行为有很大的影响,新生代的大小一般设置为整个堆空间的1/3到1/4左右

参数-XX:SurvivorRatio用来设置新生代中eden空间和from/to空间的比例关系,他的含义如下:

-XX:SurvivorRatio=eden/from=eden/to

实际工作中,堆分布的基本策略是:尽可能将对象预留在新生代,减少老年代GC的次数。

除了可以使用-Xmn指定新生代的绝对大小外,还可以使用参数-XX:NewRatio来设置新生代和老年大的比例,他的含义如下:

-XX:NewRatio=老年代/新生代

2.3 堆溢出处理

在Java程序的运行过程中,如果堆空间不足,则有可能抛出内存溢出错误(OutOfMemory),简称OOM。一旦发生这类问题,系统就会被迫退出。如果发生在生产环节,可能会引起严重的业务中断。为了不断改善系统,避免或减少这类错误的发生,需要在发生错误时,获得尽可能多的现场信息。Java虚拟机提供了参数-XX:+HeapDumpOnOutOfMemoryError,使用该参数,可以再内存溢出时导出整个堆信息。和他配合使用的还有-XX:HeapDumpPath,可以指定导出堆的存放路径。

三、非堆内存的参数配置

3.1 方法区配置

方法区主要存放类的元信息。

在JDK1.6和JDK 1.7等版本中,可以使用-XX:PermSize和-XX:MaxPermSize配置永久区大小。其中-XX:PermSize表示初始的永久区大小,-XX:MaxPermSize表示最大永久区。

在JDK 1.8中,永久区被彻底移除,使用了新的元数据区存放类的元数据。默认情况下,元数据区只受系统可用内存的限制,但依然可以使用参数-XX:MaxMetaspaceSize指定元数据区的最大可用值。

3.2 栈配置

通过-Xss指定线程的栈大小。

3.3 直接内存配置

最大可以直接内存可以使用参数-XX:MaxDirectMemorySize设置,如不设置,默认值为最大dui堆空间,即-Xmx。当直接内存使用量达到-XX:MaxDirectMemorySize时,就会触发垃圾回收,如果垃圾回收不能有效释放足够空间,直接内存溢出依然会引起系统的OOM。

四、虚拟机的工作模式

目前Java虚拟机支持Client和Server两种运行模式。默认情况下,虚拟机会根据当前计算机系统环境自动选择运行模式。使用-version参数可以查看当前的模式,如下:

java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

与Client模式相比,Server模式启动较慢,因为Server模式会尝试收集更多的系统性能信息,使用更复杂的优化算法对程序进行优化。因此,当系统完全启动并进入运行稳定期后,Server模式的执行速度会远远快于Client模式。

深入JVM-常用Java虚拟机参数的更多相关文章

  1. Java虚拟机四 常用Java虚拟机参数

    主要涉及的知识点: 1.跟踪Java虚拟机的垃圾回收和类加载等信息: 2.配置Java虚拟机的堆空间: 3.配置永久区和Java栈. 4.学习虚拟机的服务器和客户端模式. 1.1 跟踪垃圾回收 Jav ...

  2. 如何设置java虚拟机参数

    这两天在看java虚拟机,从书上看到可以自己设置java虚拟机的参数,可以方便开发人员进行系统调优和故障排查 Ecplise设置java虚拟机参数: window-->preferences-- ...

  3. java虚拟机参数设置 jvm参数设置

    java进程命令行使用方式如下: java [-options] class [args...] -options 表示虚拟机的启动参数, class为带有main()函数的java类的全名称 arg ...

  4. Java虚拟机参数设置(转)

    今天在加载一幅图片时,eclipse报出如下错误: “Exception in thread "main" java.lang.OutOfMemoryError: Java hea ...

  5. JVM之Java虚拟机详解

    这篇文章解释了Java 虚拟机(JVM)的内部架构.下图显示了遵守Java SE 7 规范的典型的 JVM 核心内部组件. 上图显示的组件分两个章节解释.第一章讨论针对每个线程创建的组件,第二章节讨论 ...

  6. JVM总结-Java 虚拟机是怎么识别目标方法(上)

    重载与重写 在 Java 程序里,如果同一个类中出现多个名字相同,并且参数类型相同的方法,那么它无法通过编译.也就是说,在正常情况下,如果我们想要在同一个类中定义名字相同的方法,那么它们的参数类型必须 ...

  7. JVM(三)-java虚拟机类加载机制

    概述: 上一篇文章,介绍了java虚拟机的运行时区域,Java虚拟机根据不同的分工,把内存划分为各个不同的区域.在java程序中,最小的运行单元一般都是创建一个对象,然后调用对象的某个 方法.通过上一 ...

  8. Java JVM——5.Java虚拟机栈

    虚拟机栈概述 由于跨平台性的设计,Java 的指令都是根据栈来设计的.不同平台CPU架构不同,所以不能设计为基于寄存器的. 栈实现的优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功 ...

  9. JVM(Java虚拟机)详解(JDK7)

    1.Java内存区域 运行时数据区域: Java 虚拟机在执行Java程序时,定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁.另外一些则是与线程 ...

随机推荐

  1. jQuery jsonp无法捕获404、500状态错误

    转载:http://www.cnblogs.com/pao8041/p/4750403.html 不过上面的这个我用的不好,下次有机会用

  2. md5加密篇(一)

    /// <summary> /// 获取文件的md5摘要 /// </summary> /// <param name="sFile">文件流& ...

  3. Stem函数绘图

    stem(n,x,'filled');第三个参数是绘图的样式,filled就是填充,将圆圈填充. Stem函数绘图各种不同的绘图函数分别适用于不同的场合,使用“stem”绘制针状图最简单,从附录中提供 ...

  4. 【JQuery】jQuery.inArray 确定第一个参数在数组中的位置

    函数:jQuery.inArray(value,array,[fromIndex]) 解释:         value:用于在数组中查找是否存在         array:待处理数组.       ...

  5. git介绍

    简介:Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件.Git ...

  6. 【日常笔记】java文件下载返回数据流形式

    @RequestMapping("/downloadFile") @ResponseBody public void download(String uploadPathUrl, ...

  7. 一个很好的UML工具

    访问地址:www.visual-paradigm.com 工具使用帮助文档地址: http://www.visual-paradigm.com/support/documents/vpumluserg ...

  8. GIT之旅【第一篇】

    初探git Linus Torvalds在2002年起,使用BitMover的版本控制软件BitKeeper管理Linux核心开发,而因为BitKeeper除商业付费版本,仅提供可免费使用但不允许修改 ...

  9. Image Segmentation的定义

    Definition 图像分割将一张图分为\(n\)个region, 需要满足下面5个条件 每一个像素都要属于一个region 每个region都是连通的 region与region之间没有交集 re ...

  10. 写chrome插件---一个优酷自动加粉丝助手

    写chrome插件主要就是写js , 我们要构造界面(HTML), 以及样式(CSS),  以及chrome给我们提供的jsAPI, 主要是chrome的API, 调试的话可以使用chrome的开发者 ...