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 ...
随机推荐
- 嵌入式Qt-4.8.6显示中文并且改变字体大小和应用自己制作的字体库
问题: QT4.8.6在移植到开发板上的时候,中文支持是必不可少的,如何让QT支持中文,如何制作QT支持的字体文件,如何使QT UI编辑器中的字号与开发板中的字号一致. 详解: 1>如何让QT支 ...
- memcached缓存分布式部署方案
一.分布式方案介绍 比较流行的两种方案: 1.取余分布: 计算key的哈希值,与服务器数量取余,得到目标服务器.优点:实现简单,当某台服务器不可用时,故障转移方便:缺点:当增减服务器时, Key与服务 ...
- 表单提交数据格式form data
前言: 最近遇到的最多的问题就是表单提交数据格式问题了. 常见的三种表单提交数据格式,分别举例说明:(项目是vue的框架) 1.application/x-www-form-urlencoded 提交 ...
- 更改jdk所用内存空间
在做项目是有时候会遇到内存jvm内存不够用的情况,在myeclipse是这样设置的. -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=128m
- BestCoder Round #11 (Div. 2) 前三题题解
题目链接: huangjing hdu5054 Alice and Bob 思路: 就是(x,y)在两个參考系中的表示演全然一样.那么仅仅可能在这个矩形的中点.. 题目: Alice and Bob ...
- APK瘦身记,怎样实现高达53%的压缩效果
作者:非戈@阿里移动安全,很多其它技术干货.请訪问阿里聚安全博客 1.我是怎么思考这件事情的 APK是Android系统安装包的文件格式.关于这个话题事实上是一个老生常谈的题目.不论是公司内部.还是外 ...
- js json简介(json的本质也是字符串)(用于服务器和客户端通信)
js json简介(json的本质也是字符串)(用于服务器和客户端通信) 一.总结 1.json的语法和js的语法非常像,只是json的键和值都是双引号,因为json的本质也是字符串 2.json是一 ...
- 又在折腾cygwin
apt-cyg https://github.com/transcode-open/apt-cyg/blob/master/README.md cygwin 163镜像 http://mirrors. ...
- Linux 系统挂载数据盘 分类: B3_LINUX 2015-01-30 18:13 228人阅读 评论(0) 收藏
适用系统:Linux(Redhat , CentOS,Debian,Ubuntu) * Linux的云服务器数据盘未做分区和格式化,可以根据以下步骤进行分区以及格式化操作. 下面的操作将会把数据盘划 ...
- iis windows phpstudy安装redis扩展
说明,我的服务器是2008 64位 php5.4.33 首先下载符合条件的redis扩展,是否符合条件可以参考https://pecl.php.net/package/redis,进入之后,点击&qu ...