说说在Java启动参数上易犯的错

作者:林昊

前几年在将OS从32 bit升级到64 bit,以及虚拟机的内存调整到8G后,我把应用的Java启动参数重新写了一版,作为目前大部分Java应用的默认启动参数模版,这几年下来,发现在这个标准版的启动参数上还是犯了一些错误的。

 

1. -XX:+DisableExplicitGC
Java在实现RMI Server的时候会通过定时的调System.gc来强制做GC(即使程序里没用到RMI也会被启动),这个动作非常烦人,另外也是为了避免应用代码上显式去调用System.gc导致一些没必要的GC动作产生,所以当时就直接加上了这个参数。

现在来看,这个参数有个挺大的问题是,Direct ByteBuffer所占用的内存以及FileChannel.map所占用的内存当达到了他们的最大阈值时,需要依赖调用System.gc来强制释放下,如果加上了这个启动参数,就意味着这个强制的释放就无效了,这会导致的一个问题是,当old gen还没到达触发full gc/cms gc的条件,而堆外的Direct ByteBuffer/FileChannel.map占用的空间又超过了它们的最大阈值时,就会直接导致OOM,而这种情况下很有可能其实是可以借助显式调用System.gc来释放出足够的空间,不过话说我仍然觉得这是JDK设计上应该改进的一点,不应该在这个时候需要依赖System.gc来管理堆外的空间,大家可以翻下FileChannel.map的代码就会发现那里在等待System.gc执行的结果是写S的等待100ms,事实上很少有full gc/cms gc可以在100ms完成。

 

不过鉴于上面的状况,如果应用里有使用到不少Direct ByteBuffer或FileChannel.map的话,建议还是不要开启-XX:+DisableExplicitGC,如果是cms gc的,还是改为加上这个参数-XX:+ExplicitGCInvokesConcurrent,另外如果有RMI Server这种定时GC影响的,再调整下-Dsun.rmi.dgc.client.gcInterval和-Dsun.rmi.dgc.server.gcInterval这两个时间吧,时间单位是ms,也可以设置为Long.MAX_VALUE。

 

2. 缺少-XX:+UseCMSInitiatingOccupancyOnly
由于我们的Java应用的heap基本都是大于4G的,所以都是用的CMS,当时我在写启动参数的时候一直犹豫要不要加上-XX:+UseCMSInitiatingOccupancyOnly这个参数,一犹豫就没加,但事实上后来碰到了不少应用由于JVM自行触发CMS GC的机制导致CMS GC频繁,所以建议用CMS GC的场景下还是加上这个参数更稳妥。

 

3. -XX:MaxDirectMemorySize
话说在写启动参数的时候我都压根不知道这参数(要知道Java到底有哪些启动参数可用,以及默认值是多少,最靠谱的方法是在启动参数上加-XX:+PrintFlagsFinal或用jinfo -flags [pid]来查看),后来是由于有一次出现了有应用物理内存被耗光,排查的时候才发现是Direct ByteBuffer这块默认的大小是heap size,所以在有些情况下可能会出现Direct ByteBuffer这里占用了大量的空间,但heap这边又还不到触发Full gc/CMS gc的条件,就会有可能导致物理内存被耗光。
因此对于远程交互比较多的应用,建议还是加上这个参数,合理控制大小,不要让heap size+Direct Memory Size就把物理内存给耗光了。

 

ps: 关于Java常见问题的排查方法,重新专门写了一个PPT,涵盖了以下几种常见的Java问题的排查方法:
1. 类加载问题,例如NoSuchMethodException;
2. 内存问题,例如各种OOM;
3. 应用无响应问题,例如http访问后返回499;
4. CPU利用率问题,例如us耗尽;
5. Java进程退出问题。

时间: 2024-08-31 13:03:36

说说在Java启动参数上易犯的错的相关文章

java虚拟机启动参数分类详解

HotSpot是较新的Java虚拟机技术,用来代替JIT(Just in Time)技术,可以大大提高Java运行的性能.Java原先是把源代码编译为字节码在虚拟机执行,这样执行速度较慢.而该技术将常用的部分代码编译为本地(原生,native)代码,这样显著提高了性能.用于服务器版和标准版的HotSpot有所不同. java启动参数共分为三类: 其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容: 其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有

5种易犯的PHP数据库错误

 5种易犯的PHP数据库错误---包括数据库模式设计.数据库访问和使用数据库的业务逻辑代码---以及它们的解决方案. 如果只有一种 方式使用数据库是正确的--  您可以用很多的方式创建数据库设计.数据库访问和基于数据库的 PHP 业务逻辑代码,但最终一般以错误告终.本文说明了数据库设计和访问数据库的 PHP 代码中出现的五个常见问题,以及在遇到这些问题时如何修复它们. 问题 1:直接使用 MySQL 一个常见问题是较老的 PHP 代码直接使用 mysql_ 函数来访问数据库.清单 1 展示了如何

十个JavaScript中易犯的小错误,你中了几枪?

在今天,JavaScript已经成为了网页编辑的核心.尤其是过去的几年,互联网见-证了在SPA开发.图形处理.交互等方面大量JS库的出现. 如果初次打交道,很多人会觉得js很简单.确实,对于很多有经验的工程师,或者甚至是初学者而言,实现基本的js功能几乎 毫无障碍.但是JS的真实功能却比很多人想象的要更加多样.复杂.JavaScript的许多细节规定会让你的网页出现很多意想不到的bug,搞懂这些 bug,对于成为一位有经验的JS开发者很重要. 常见错误一:对于this关键词的不正确引用 我曾经听

开发者必看:最易犯的Top 10加密错误,你中枪了吗?

本文讲的是开发者必看:最易犯的Top 10加密错误,你中枪了吗?, 在对小型初创企业和大型银行和电信公司进行了数百次安全代码审查,并阅读了数百个在安全社区发布的堆栈溢出的帖子之后,我们列出了开发人员最容易犯的十大加密错误. 不幸的现实是,错误的加密方式随处可见.正确加密的次数远远低于我们发现的错误加密的次数,许多问题是由于复杂的加密API在默认的情况下是不安全的.另一个原因是,我们需要训练有素的专家进行手动代码分析才能发现问题.根据我的经验,流行的静态分析工具在寻找加密问题方面并不出色,此外,黑

[Java]jvm参数选项中文文档

本文是基于最新的SUN官方文档Java SE 6 Hotspot VM Options 编写的译文.主要介绍JVM中的非稳态选项及其使用说明. 为了让读者明白每个选项的含义,作者在原文基础上补充了大量的资料.希望这份文档,对正在研究JVM参数的朋友有帮助!  另外,考虑到本文档是初稿,如有描述错误,敬请指正.  非稳态选项使用说明 -XX:+<option> 启用选项 -XX:-<option> 不启用选项 -XX:<option>=<number> 给选项

10个JavaScript中易犯小错误_javascript技巧

在今天,JavaScript已经成为了网页编辑的核心.尤其是过去的几年,互联网见证了在SPA开发.图形处理.交互等方面大量JS库的出现. 如果初次打交道,很多人会觉得js很简单.确实,对于很多有经验的工程师,或者甚至是初学者而言,实现基本的js功能几乎毫无障碍.但是JS的真实功能却比很多人想象的要更加多样.复杂.JavaScript的许多细节规定会让你的网页出现很多意想不到的bug,搞懂这些bug,对于成为一位有经验的JS开发者很重要. 常见错误一:对于this关键词的不正确引用 我曾经听一位喜

java 连接异常-java 启动jdbc 事务报错 嵌套异常

问题描述 java 启动jdbc 事务报错 嵌套异常 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC

内部类-java方法参数的修饰符问题

问题描述 java方法参数的修饰符问题 java在写方法时,为什么有的方法参数用final修饰? 还有就是内部类存在的意义是什么? 也就是说方法中的内部类和类中的内部类各有什么应用场景(请有实战经验的大神各自举个例子)? //问题补充(关于方法中的内部类) 我的意思是: pubic class TestClass{ public void fun(){ public class Test1{ //........ } } } 解决方案 为了实现一些内容,常常需要这么玩: public void

Tokyo Tyrant(TTServer)系列:启动参数和配置

启动参数介绍 继续上一篇Tokyo Tyrant(TTServer)系列-介绍和安装,我们继续来看启动 参数和配置. ttserver命令可以启动一个数据库实例.因为数据库已经实现了Tokyo Cabinet的抽象API,所以可以在启动的时候指定数据库的配置类型. 支持的数据库类型有: 内存hash数据库 内存tree数据库 hash数据库 B+ tree数据库, 命令通过下面的格式来使用,'dbname'制定数据库名,如果省略,则被视作 内存hash数据库. ttserver [-host n