JVM参数调优:Eclipse启动实践
本文主要参考自《深入理解 Java 虚拟机》。这本书是国人写的难得的不是照搬代码注释的且不是废话连篇的技术书,内容涵盖了 Java 从源码到字节码到执行的整个过程,包括了 JVM(Java Virtual Machine)的架构,垃圾收集的介绍等。这里摘录出关于配置 JVM 基本参数来调优 Eclipse 启动的过程,比较初级,供初学者参考。
基础知识
针对 JVM 的参数调优主要集中在数据区大小的控制和垃圾回收策略的选择。关于 JVM 运行机制等更多内容可参考其他博文
JVM 的运行时数据区
运行时 JVM 的数据区主要包括各线程私有的栈和程序计数器,线程共享的方法区,以及管理对象的堆(又称回收堆)等。程序运行时,类信息、常量、静态变量等会被加载到方法区。运行过程中几乎所有对象都在堆里,内存占用的空间最大,这也是最值得优化得部分。
JVM 的垃圾回收策略
Java 程序中,除了基本类型(primitive types),其他的数据都是以对象的形式存在。对象生命周期有长有短,如果无区别的保留在内存中,会造成内存超载。内存垃圾回收(Garbage Collection, 缩写 GC)就是解决这一问题的策略。
注意:JVM 不仅仅只对对象进行垃圾回收,实际上也会对废弃常量和无用的类做回收。
垃圾回收首先得找到需要被回收的对象,一般采用根搜索算法来标记处这些过时的对象(另外有一种简单的实现:引用计数,但存在明显的弊端,即循环引用)。
回收垃圾的过程会消耗计算资源和时间。根据不同的处理方式,垃圾回收有不同的策略,现在常用的是分代收集算法:根据对象的存活周期将堆划分为几代:新生代(Young Generation 或 New Generation)和老生代(Tenured Generation),HotSpot 虚拟机里还分出了永生代(基本等同于方法区)。不同代采用不同的垃圾回收策略。
HotSpot 虚拟机
HotSpot 虚拟机中,Perm 代指永生代,Old 代指老年代,而新生代使用复制算法,将区域划分为三块:Eden,S0 和 S1(S 是 Survivor 的缩写)。
IBM 研究表明,新生代中的对象 98%是朝生夕死的,三者的比例划分是 8:1:1。对象先分配到 Eden,如果 Eden 中内存占用量达到一定得比例,触发 Minor GC,JVM 会将 Eden 和 S0(或 S1)中存活的对象复制到 S1(或 S0),并清空 Eden 和 S0(或 S1)。如果同时老年代的内存占用量打达到一定比例,会触发 Major GC(也称 Full GC)。通常 Major GC 比 Minor GC 慢 10 倍以上。
编译过程
Java 一直号称“Write once, run anywhere”,这个特性正是由 JVM 这一虚拟层来支撑的。
Java 源代码首先编译为 Java 字节码,字节码再被 JVM 加载运行。运行的过程可以是直接针对字节码的解释执行,也可以是经过了 JIT(Just in time)编译为机器码后的执行。另外,还有静态提前编译器(Ahead Of Time,也缩写为 AOT),能将源码直接编译为机器码。
HotSpot 虚拟机的 JIT 编译器有:Client Complier(简称 C1)、Server Complier(简称 C2)以及在 Java7 中堆出的分层编译器。C1 编译器做一些快速的优化,C2 做一些更耗时的优化但是产生更高效的代码,而分层编译器则结合了两者的优点:快速的启动和逐步的优化(brings client startup speeds to the server VM)。
性能监控和故障处理工具
对于系统调优和问题定位,周志明在《深入 Java 虚拟机》中总结到
给一个系统定位问题的时候,知识、经验是关键基础,数据是依据,工具是运用知识处理数据的手段。这里说的数据包括:运行日志、异常堆栈、GC 日志、线程快照、堆转储快照等……应当意识到工具永远都是知识技能的一层包装,没有什么工具是“秘密武器”。
Java 提供了很多工具给开发者来监控和处理运行中的问题。包括命令行工具以及可视化工具
命令行工具
比如 jps, jstat, jinfo 等。举例如下:
1 |
|
可视化工具
- JConsole:比较老得分析软件,Java 自带。Windows 下搜 jconsole.exe,Mac 下启动命令为 jconsole
- Eclipse Memory Analyzer Tool:用于分析 dump 下的堆数据
- VisualVM:推荐,很全能的分析工具
JVM 参数
这里零散的罗列了一些我用到的简单的 JVM 配置参数:
内存大小控制:
- -Xmx20M: 堆的最大值
- -Xms10M: 堆的初始分配内存
- -Xmn: 新生代堆的分配内存
- -Xss128k: 线程的栈空间大小
- -XX:PermSize=10M | 方法区初始大小
- -XX:MaxPermSize=10M |方法区最大值
编译相关:
- -Xint: 关闭 JIT,完全使用解释执行,实践中没什么作用,解释执行很慢。
- -client: 启动 C1 编译器
- -server: 启动 C2 编译器
- -XX:+TieredCompilation: 启动分层编译器
其他:
- -XX:+DisableExplicitGC: 屏蔽 System.gc()调用
- -PrintGCDetails: 让 jvm 在每次发生 gc 的时候打印日志,利于分析 gc 的原因和状况
- -XX:+HeapDumpOnOutOfMemoryError: 内存溢出时 dump 下 heap,可以通过 Eclipse Memory Analyzer Tool 打开查看。
- -XX:HeapDumpPath=/: dump 下的 heap 文件快照的路径。Eclipse 中默认放到项目的根目录中
- -XVerify:none: 禁止字节码验证
调优 Eclipse 启动的实践
实践环境
- CPU: 2.8 GHz Intel Core i7
- 内存: 8 GB 1333 MHz DDR3
- 操作系统: OS X 10.9.1(64bits)
- Eclipse:Version: Kepler Service Release 1, Build id: 20130919-0819
- Java:java version “1.7.0_45”
调优实践
调优 Eclipse 启动实际上就是调优 Eclipse 在 JVM 中的加载和程序启动阶段的运行。由于默认的 Ecpise 启动配置无法适应所有不同的硬件、软件环境,做针对性的调优是必要的。
Eclipse 的启动配置文件是 eclipse.ini,对 JVM 的参数调优直接在该文件中修改。OS X 下,其文件路径为 $ECLIPSE/Eclipse.app/Contents/MacOS/eclipse.ini(注意不是 Eclipse 文件包根目录下得 eclipse.ini)。
测 Eclipse 启动时间
要优化 Eclipse 的启动时间,先要能确定 Eclipse 的启动时间。这里推荐网友实现的一个 Eclipse 插件:计算启动时间的 Eclipse 插件。下载后放到 Eclipse 的插件包中,启动 Eclipse 即可看到弹窗显示的启动时间。为了得到一个尽可能公平的测试结果,需要在测试过程中关闭其他程序,避免 CPU 负载带来的误差,并多次测试取平均值。
调优策略
使用 VisualVM 查看程序的运行状况来定位瓶颈,尝试调优解决。下图是 VisualVM 的示例图,右边图示展示了 GC 的状态以及编译时间、类加载时间和垃圾回收时间等指标。

也可以通过命令行工具查看 GC 的状态,比如:jstat -gc XXX #其中 XXX 是 jps 查出的进程的 LVMID.
我的实践总结如下:
- 类加载时间过长:禁止加载类时的字节码验证。我们认为 Eclipse 的字节码是可靠的。
-XVerify:none - 编译时间:
-client缩短了编译时间,但长期运行的性能可能受影响,-server编译时间长,而编译优化做得更多,后期使用汇报大,-XX:+TieredCompilation分层编译则集合了前两者的优势。没有特殊需求,可选用这一编译选项。 - Minor GC 次数太多:新生代空间太小,加大新生代的内存大小。
-Xmn800m,同时,增大回收堆的总大小上限(-Xmx1024m)。 - Full GC 次数太多:为了避免回收堆由小到大的动态增长增加时间开销,可将其初始大小跟最大上限设定为同一值
-Xms1024m,并增加老年代的大小(-XX:PermSize=256m,-XX:MaxPermSize=256m)。 - 代码中的 GC 调用:Eclipse 代码中有 System.GC()的调用可能促使 JVM 执行垃圾回收,可以通过
-XX:+DisableExplicitGC来防止。 - 垃圾收集器的选择:垃圾收集器有很多,比如 Serial、ParNew、Parallel Scavenge、CMS、G1 等。推荐使用老生代 CMS 新生代 ParNew 的组合来应对 Eclipse 用户交互频繁的情况(
-XX:+UseParNewGC、-XX:+UserConcMarkSweepGC)。同时提升 CMS 的垃圾回收的触发条件:-XX:CMSInitiatingOccupancyFraction=85,进一步降低 Full GC 的出现。
最终 eclipse.ini
1 |
|
其他参考
- 《JVM 的 GC 简介和实例》 — 搜索技术博客-淘宝.昆仑
原文地址:http://biaobiaoqi.me/blog/2014/01/17/java-performance-tunning-in-practice/
版权声明:自由转载-非商用-非衍生-保持署名| Creative Commons BY-NC-ND 3.0
JVM参数调优:Eclipse启动实践的更多相关文章
- JVM参数调优
JVM参数调优 JVM参数调优是一个很头痛的问题,可能和应用有关系,下面是本人一些调优的实践经验,希望对读者能有帮助,环境LinuxAS4,resin2.1.17,JDK6.0,2CPU,4G内存,d ...
- (转)JVM参数调优八大技巧
这里和大家分享一下JVM参数调优的八条经验,JVM参数调优,这是很头痛的问题,设置的不好,JVM不断执行FullGC,导致整个系统变得很慢,网站停滞时间能达10秒以上,相信通过本文的学习你对JVM参数 ...
- 性能测试三十六:内存溢出和JVM常见参数及JVM参数调优
堆内存溢出: 此种溢出,加内存只能缓解问题,不能根除问题,需优化代码堆内存中存在大量对象,这些对象都有被引用,当所有对象占用空间达到堆内存的最大值,就会出现内存溢出OutOfMemory:Java h ...
- 【学习】011 JVM参数调优配置
自动内存管理机制 Java虚拟机原理 所谓虚拟机,就是一台虚拟的机器.他是一款软件,用来执行一系列虚拟计算指令,大体上虚拟机可以分为 系统虚拟机和程序虚拟机, 大名鼎鼎的Visual Box.Vmar ...
- SpringBoot-内部运行jvm参数调优
SpringBoot JVM参数调优 这个根据服务器的内存大小,来设置堆参数. -Xms :设置Java堆栈的初始化大小 -Xmx :设置最大的java堆大小 实例参数-XX:+PrintGCDeta ...
- Java后端进阶-JVM参数调优
package com.study.performance; import org.springframework.boot.SpringApplication; import org.springf ...
- JVM参数调优总结
一.前言 要想成为一名高级Java开发具备JVM调优的能力必不可少,能够根据项目实际情况进行JVM调优的前提是理解JVM原理和常用JVM参数的含义及作用,虽然<深入理解Java虚拟机>这本 ...
- jvm 参数调优
FROM: http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html#CMSInitiatingOccupancyFraction ...
- JVM 参数调优配置
在 tomcat 配置文件 tomcat/bin/catalina.sh 中 配置 JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xss1024K -XX ...
随机推荐
- 每天自动备份MySQL数据库的shell脚本
经常备份数据库是一个好习惯,虽然数据库损坏或数据丢失的概率很低,但一旦发生这种事情,后悔是没用的.一般网站或应用的后台都有备份数据库的功能按钮,但需要去手工执行.我们需要一种安全的,每天自动备份的方法 ...
- GO语言学习(六)Go 语言数据类型
在 Go 编程语言中,数据类型用于声明函数和变量. 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. Go 语言按类别有以下几种 ...
- 实现span设置宽度(行内元素本来不支持调宽度高度这些样式)(变成行内块元素:display:inline-block;)
实现span设置宽度(行内元素本来不支持调宽度高度这些样式)(变成行内块元素:display:inline-block;) 一.总结 1.将span从行内元素变成行内快元素就可以调了: 设置样式的时候 ...
- RTC时钟和BKP的配置stm32
摘自:https://blog.csdn.net/gtkknd/article/details/52233605 RTC和后备寄存器通过一个开关供电,在VDD有效的时候选择VDD供电,否则选择VBAT ...
- 【hdu 6208】The Dominator of Strings
[链接]h在这里写链接 [题意] 问你n个串里面有没有一个串,使得其余n-1个串都是他的子串. [题解] 后缀数组. 答案肯定是那个最长的串. 则,把那个串求一下Sa数组(注意仅仅那个最长的串求). ...
- SpringBoot错误信息总结(不定时更新)
1." java.lang.IllegalStateException: @Bean method ShiroConfig.cacheManager called as a bean ref ...
- Eclipse查看某个方法被哪些类调用
方法一:打开该类,在类的定义上即类名上,右键-->References--->Project ,就可以查看该类是否被工程中的其他Java文件引用过:但是如果在JSP页面,这个方法查不出来 ...
- mina架构分析
使用的版本号是2.0.9 IoService分析 AbstractIoAcceptor定义了全部的public接口,并定义了子类须要实现的bindInternal函数,AbstractPollingI ...
- 在Eclipse中运行Nutch2.3 分类: H3_NUTCH 2015-01-28 16:41 3175人阅读 评论(13) 收藏
参考http://wiki.apache.org/nutch/RunNutchInEclipse 一.环境准备 1.下载nutch2.3源代码 wget http://mirror.bit.edu.c ...
- [D3] Load and Inspect Data with D3 v4
You probably use a framework or standalone library to load data into your apps, but what if that’s o ...