文档章节

JVM 垃圾回收器与参数配置

秋风醉了
 秋风醉了
发布于 2017/09/06 18:27
字数 2437
阅读 37
收藏 0
点赞 0
评论 0

JVM 垃圾回收器与参数配置

JVM参数概述

详见:http://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

主要分为以下几类:

主要有标准参数(java -help) 和 非标准参数(java -X)还有以XX开头的非标准参数(Advanced Runtime Options)。

1)标准参数

These are the most commonly used options that are supported by all implementations of the JVM.

可以通过 java -help 命令列出。

2) 非标准参数(Non-Standard Options)

These options are general purpose options that are specific to the Java HotSpot Virtual Machine.

可以通过java -X 命令列出。

➜  ~ java -X
    -Xmixed           混合模式执行 (默认)
    -Xint             仅解释模式执行
    -Xbootclasspath:<用 : 分隔的目录和 zip/jar 文件>
                      设置搜索路径以引导类和资源
    -Xbootclasspath/a:<用 : 分隔的目录和 zip/jar 文件>
                      附加在引导类路径末尾
    -Xbootclasspath/p:<用 : 分隔的目录和 zip/jar 文件>
                      置于引导类路径之前
    -Xdiag            显示附加诊断消息
    -Xnoclassgc       禁用类垃圾收集
    -Xincgc           启用增量垃圾收集
    -Xloggc:<file>    将 GC 状态记录在文件中 (带时间戳)
    -Xbatch           禁用后台编译
    -Xms<size>        设置初始 Java 堆大小
    -Xmx<size>        设置最大 Java 堆大小
    -Xss<size>        设置 Java 线程堆栈大小
    -Xprof            输出 cpu 配置文件数据
    -Xfuture          启用最严格的检查, 预期将来的默认值
    -Xrs              减少 Java/VM 对操作系统信号的使用 (请参阅文档)
    -Xcheck:jni       对 JNI 函数执行其他检查
    -Xshare:off       不尝试使用共享类数据
    -Xshare:auto      在可能的情况下使用共享类数据 (默认)
    -Xshare:on        要求使用共享类数据, 否则将失败。
    -XshowSettings    显示所有设置并继续
    -XshowSettings:all
                      显示所有设置并继续
    -XshowSettings:vm 显示所有与 vm 相关的设置并继续
    -XshowSettings:properties
                      显示所有属性设置并继续
    -XshowSettings:locale
                      显示所有与区域设置相关的设置并继续

-X 选项是非标准选项, 如有更改, 恕不另行通知。

比较常用的两个参数   

-Xms<size>        设置初始 Java 堆大小

-Xmx<size>        设置最大 Java 堆大小

3)以XX开头的非标准参数(Advanced Runtime Options)

These options control the runtime behavior of the Java HotSpot VM.

所有的XX参数都以”-XX:”开始,但是随后的语法不同,取决于参数的类型。

  1. 对于布尔类型的参数,我们有”+”或”-“,然后才设置JVM选项的实际名称。例如,-XX:+option 用于启用选项,而-XX:-option用于关闭选项。
  2. 对于需要非布尔值的参数,如string或者integer,我们先写参数的名称,后面加上”=”,最后赋值。例如, -XX:option=值。

 

Java demo

package com.rocketmq.jvmtest;

public class JvmTestMain01 {
    public static void main(String[] args) {
        //=====================Begin=========================
        System.out.print("Xmx=");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");

        System.out.print("free mem=");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");

        System.out.print("total mem=");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");

        //=====================First Allocated=========================
        System.out.println("5MB array allocated");
        byte[] b1 = new byte[5 * 1024 * 1024];
        //=====================First Allocated end=========================

        System.out.print("Xmx=");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");

        System.out.print("free mem=");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");

        System.out.print("total mem=");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");

        //=====================Second Allocated=========================
        System.out.println("10MB array allocated");
        byte[] b2 = new byte[10 * 1024 * 1024];
        //=====================Second Allocated end=========================

        System.out.print("Xmx=");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");

        System.out.print("free mem=");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");

        System.out.print("total mem=");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");

        //=====================OOM=========================
        System.out.println("OOM!!!");
        System.gc();
        byte[] b3 = new byte[40 * 1024 * 1024];
    }
}

shell 脚本

#!/bin/sh

error_exit ()
{
    echo "ERROR: $1 !!"
    exit 1
}
# -e filename 表示文件是否存在
# $HOME 取默认的环境变量 HOME 变量
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=$HOME/jdk/java
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
[ ! -e "$JAVA_HOME/bin/java" ] && error_exit "Please set the JAVA_HOME variable in your environment, We need java(x64)!"

# 通过 export 命令导出到全局环境变量中
# ${var} 返回变量值 推荐这种写法 可以使代码的可读性更好避免歧义
# $(dirname $0) 返回这个脚本文件放置的目录
# export BASE_DIR=$(dirname $0)/.. 设置BASE_DIR为脚本文件放置的目录的上级目录
# 比如 cd ./..  返回上级目录
export JAVA_HOME
export JAVA="$JAVA_HOME/bin/java"
export BASE_DIR=$(dirname $0)/..
export CLASSPATH=.:${BASE_DIR}:${CLASSPATH}

#===========================================================================================
# JVM Configuration
#  -Xms<size>        设置初始 Java 堆大小
#  -Xmx<size>        设置最大 Java 堆大小
#  -Xmnsize Sets the initial and maximum size (in bytes) of the heap for the young generation (nursery).
#===========================================================================================
JAVA_OPT="${JAVA_OPT} -Xms50m -Xmx50m -Xmn20m"
JAVA_OPT="${JAVA_OPT} -XX:+UseSerialGC -XX:SurvivorRatio=8"
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/Users/xinxingegeya/logs/test_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"

# $@ 是传给脚本的所有参数的列表
$JAVA ${JAVA_OPT} $@

 

使用 SerialGC 以及参数设置

SerialGC的特点以及使用场景

The serial collector is the default for client style machines in Java SE 5 and 6. With the serial collector, both minor and major garbage collections are done serially (using a single virtual CPU). In addition, it uses a mark-compact collection method. This method moves older memory to the beginning of the heap so that new memory allocations are made into a single continuous chunk of memory at the end of the heap. This compacting of memory makes it faster to allocate new chunks of memory to the heap.

The Serial GC is the garbage collector of choice for most applications that do not have low pause time requirements and run on client-style machines. It takes advantage of only a single virtual processor for garbage collection work (therefore, its name). Still, on today's hardware, the Serial GC can efficiently manage a lot of non-trivial applications with a few hundred MBs of Java heap, with relatively short worst-case pauses (around a couple of seconds for full garbage collections).

Another popular use for the Serial GC is in environments where a high number of JVMs are run on the same machine (in some cases, more JVMs than available processors!). In such environments when a JVM does a garbage collection it is better to use only one processor to minimize the interference on the remaining JVMs, even if the garbage collection might last longer. And the Serial GC fits this trade-off nicely.

Finally, with the proliferation of embedded hardware with minimal memory and few cores, the Serial GC could make a comeback.

指定 -XX:+UseSerialGC 参数,运行程序 打印如下:

➜  bin git:(master) ✗ ./runjavademo.sh com.rocketmq.jvmtest.JvmTestMain01 
Xmx=48.0M
free mem=46.3994140625M
total mem=48.0M
5MB array allocated
Xmx=48.0M
free mem=41.39939880371094M
total mem=48.0M
10MB array allocated
Xmx=48.0M
free mem=32.219390869140625M
total mem=48.0M
OOM!!!
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at com.rocketmq.jvmtest.JvmTestMain01.main(JvmTestMain01.java:44)

gc日志如下,

Java HotSpot(TM) 64-Bit Server VM (25.51-b03) for bsd-amd64 JRE (1.8.0_51-b16), built on Jun  8 2015 18:01:11 by "java_re" with gcc 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Memory: 4k page, physical 8388608k(170788k free)

/proc/meminfo:

CommandLine flags: -XX:InitialHeapSize=52428800 -XX:MaxHeapSize=52428800 -XX:MaxNewSize=20971520 -XX:NewSize=20971520 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseSerialGC 
0.310: [GC (Allocation Failure) 0.310: [DefNew: 6758K->471K(18432K), 0.0104152 secs] 6758K->5591K(49152K), 0.0105287 secs] [Times: user=0.00 sys=0.01, real=0.01 secs] 
0.326: [Full GC (System.gc()) 0.326: [Tenured: 5120K->15828K(30720K), 0.0167847 secs] 16159K->15828K(49152K), [Metaspace: 2802K->2802K(1056768K)], 0.0168987 secs] [Times: user=0.01 sys=0.01, real=0.02 secs] 
0.343: [GC (Allocation Failure) 0.343: [DefNew: 0K->0K(18432K), 0.0017802 secs]0.345: [Tenured: 15828K->15828K(30720K), 0.0027776 secs] 15828K->15828K(49152K), [Metaspace: 2802K->2802K(1056768K)], 0.0046659 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
0.348: [Full GC (Allocation Failure) 0.348: [Tenured: 15828K->15817K(30720K), 0.0049611 secs] 15828K->15817K(49152K), [Metaspace: 2802K->2802K(1056768K)], 0.0050123 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
 def new generation   total 18432K, used 814K [0x00000007bce00000, 0x00000007be200000, 0x00000007be200000)
  eden space 16384K,   4% used [0x00000007bce00000, 0x00000007bcecbb28, 0x00000007bde00000)
  from space 2048K,   0% used [0x00000007bde00000, 0x00000007bde00000, 0x00000007be000000)
  to   space 2048K,   0% used [0x00000007be000000, 0x00000007be000000, 0x00000007be200000)
 tenured generation   total 30720K, used 15817K [0x00000007be200000, 0x00000007c0000000, 0x00000007c0000000)
   the space 30720K,  51% used [0x00000007be200000, 0x00000007bf172750, 0x00000007bf172800, 0x00000007c0000000)
 Metaspace       used 2833K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 306K, capacity 386K, committed 512K, reserved 1048576K

等下篇文章记录一下gc日志的分析过程。

 

使用 Parallel GC 以及参数设置

Parallel GC的特点

The parallel garbage collector uses multiple threads to perform the young genertion garbage collection. By default on a host with N CPUs, the parallel garbage collector uses N garbage collector threads in the collection. The number of garbage collector threads can be controlled with command-line options:

-XX:ParallelGCThreads=<desired number>

On a host with a single CPU the default garbage collector is used even if the parallel garbage collector has been requested. On a host with two CPUs the parallel garbage collector generally performs as well as the default garbage collector and a reduction in the young generationgarbage collector pause times can be expected on hosts with more than two CPUs. The Parallel GC comes in two flavors.

Usage Cases

The Parallel collector is also called a throughput collector. Since it can use multilple CPUs to speed up application throughput. This collector should be used when a lot of work need to be done and long pauses are acceptable. For example, batch processing like printing reports or bills or performing a large number of database queries.

-XX:+UseParallelGC

With this command line option you get a multi-thread young generation collector with a single-threaded old generation collector. The option also does single-threaded compaction of old generation.

Here is a sample command line for starting the Java2Demo:

java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseParallelGC -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar

-XX:+UseParallelOldGC

With the -XX:+UseParallelOldGC option, the GC is both a multithreaded young generation collector and multithreaded old generation collector. It is also a multithreaded compacting collector. HotSpot does compaction only in the old generation. Young generation in HotSpot is considered a copy collector; therefore, there is no need for compaction.

Compacting describes the act of moving objects in a way that there are no holes between objects. After a garbage collection sweep, there may be holes left between live objects. Compacting moves objects so that there are no remaining holes. It is possible that a garbage collector be a non-compacting collector. Therefore, the difference between a parallel collector and a parallel compacting collector could be the latter compacts the space after a garbage collection sweep. The former would not.

Here is a sample command line for starting the Java2Demo:

java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseParallelOldGC -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar

 

使用 Concurrent Mark Sweep (CMS) Collector 以及参数设置

Concurrent Mark Sweep (CMS) Collector 特点

The Concurrent Mark Sweep (CMS) collector (also referred to as the concurrent low pause collector) collects the tenured generation. It attempts to minimize the pauses due to garbage collection by doing most of the garbage collection work concurrently with the application threads. Normally the concurrent low pause collector does not copy or compact the live objects. A garbage collection is done without moving the live objects. If fragmentation becomes a problem, allocate a larger heap.

Note: CMS collector on young generation uses the same algorithm as that of the parallel collector.

Usage Cases

The CMS collector should be used for applications that require low pause times and can share resources with the garbage collector. Examples include desktop UI application that respond to events, a webserver responding to a request or a database responding to queries.

Command Line Switches

To enable the CMS Collector use:

-XX:+UseConcMarkSweepGC

and to set the number of threads use:

-XX:ParallelCMSThreads=<n>

Here is a sample command line for starting the Java2Demo:

java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseConcMarkSweepGC -XX:ParallelCMSThreads=2 -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar

 

使用 G1 Garbage Collector 以及参数设置

G1 Garbage Collector 特点

The Garbage First or G1 garbage collector is available in Java 7 and is designed to be the long term replacement for the CMS collector. The G1 collector is a parallel, concurrent, and incrementally compacting low-pause garbage collector that has quite a different layout from the other garbage collectors described previously. However, detailed discussion is beyond the scope of this OBE.

Command Line Switches

To enable the G1 Collector use:

-XX:+UseG1GC

Here is a sample command line for starting the Java2Demo:

java -Xmx12m -Xms3m -XX:+UseG1GC -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar

==========END==========

© 著作权归作者所有

共有 人打赏支持
秋风醉了
粉丝 229
博文 577
码字总数 407134
作品 0
朝阳
程序员
Java GC系列:Java垃圾回收详解

Java的内存分配与回收全部由JVM垃圾回收进程自动完成。与C语言不同,Java开发者不需要自己编写代码实现垃圾回收。这是Java深受大家欢迎的众多特性之一,能够帮助程序员更好地编写Java程序。 ...

满风
2015/04/10
0
0
Java虚拟机(JVM)(自动内存管理机制)

简介 Java虚拟机(JVM)是Java应用的运行环境,从一般意义上来讲,JVM是通过规范来定义的一个虚拟的计算机,被设计用来解释执行从Java源码编译而来的字节码。 体系结构 JVM主要有子系统和内存...

亚特兰缇斯
2015/03/05
0
0
Jvm堆内存的划分结构和优化,垃圾回收详解(详细解答篇)

在JVM中堆空间划分如下图所示 上图中,刻画了Java程序运行时的堆空间,可以简述成如下2条 1.JVM中堆空间可以分成三个大区,新生代、老年代、永久代 2.新生代可以划分为三个区,Eden区,两个幸...

嘻哈开发者
07/17
0
0
【转】Java虚拟机参数 -XX等相关参数应用

通常,我们为了避免内存溢出等问题,需要设置环境变量 JAVA_OPTS -Xms256M -Xmx512M 等,【对于服务器,一般都设置成一样的】 但是有的时候可能这样的设置还会不行(比如,当Server应用程序加...

晨曦之光
2012/03/09
0
0
《成神之路-基础篇》JVM——垃圾回收(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收 ...

05/05
0
0
JAVA虚拟机 JVM 详细分析 原理和优化(个人经验+网络搜集整理学习)

JVM是java实现跨平台的主要依赖就不具体解释它是什么了 ,简单说就是把java的代码转化为操作系统能识别的命令去执行,下面直接讲一下它的组成 1.ClassLoader(类加载器) 加载Class 文件到内...

小海bug
06/14
0
0
聊聊JAVA虚拟机中的垃圾收集器

前言 JAVA虚拟机的垃圾收集器是虚拟机内存的清道夫,它的存在让JAVA开发人员能将更多精力投入到业务研发上。了解垃圾收集器,并利用好这个工具,能更好的保障服务稳定性。这篇文章通过分析J...

lilugoodjob
07/02
0
0
Java的垃圾回收之算法[转]

引言 Java的堆是一个运行时数据区,类的实例(对象)从中分配空间。Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new、newarray、anewarray和multianewarray等...

kext
2012/03/20
0
0
JVM调优总结(5):典型配置

JVM调优总结(5):典型配置 2016-04-20(点击上方公众号,可快速关注) 来源:pengjiaheng网址:http://pengjiaheng.iteye.com/blog/538582 以下配置主要针对分代垃圾回收算法而言。 堆大小...

舒文joven
07/17
0
0
JVM汇总--jvm调优-命令篇

GC的最根本原因:垃圾收集器的工作就是清除Java创建的对象,垃圾收集器需要清理的对象数量以及要执行的GC数量均取决于已创建的对象数量。因此,为了使你的系统在GC上表现良好,首先需要减少创...

素雷
04/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

设计神器 - 摹客设计系统上线了 | 晒出你的设计规范,赢iPad Pro!

在国内,设计规范也许还是个不太常用的概念,但是如果你正好有参与互联网公司的产品设计,你应该早就已经体会到设计规范的重要性了。UI设计师总是要花费大量的时间和精力向开发描述一大堆设计...

mo311
9分钟前
0
0
Thymeleaf 使用过程中的一些记录

Thymeleaf格式化时间: th:value="${#dates.format(gw.regDT,'yyyy-MM-ddHH:mm:ss')}" Thymeleaf select反选: <select id="status" name="status" th:field="${gw.status}" th:value="${gw.......

惊尘大人
12分钟前
0
0
istio源码分析之pilot-discovery模块分析

本文分析的istio代码版本为0.8.0,commit为0cd8d67,commit时间为2018年6月18日。 本文为Service Mesh深度学习系列之一: Service Mesh深度学习系列part1—istio源码分析之pilot-agent模块分...

xiaomin0322
17分钟前
0
0
数据库基本操作:增删改查及联表操作

所用软件:SQL Server Management Studio 首先第一步,建立一个表。在这里命名为T1。并在里面填入几条数据。如图: T1 一.查询 查询所有:select * from T1; 按条件查询:select * from T1 ...

小_橙_子
21分钟前
0
0
Crontab作业时间设置

今天,遇到这么一个题目,周一到周五的9:00-16:59之间,每隔两分钟将某个命令运行一次。给的答案是: */2 9-16 * * 1-5 /usr/sbin/somecommand dosomething 乍一看,这个答案不对,应...

大别阿郎
26分钟前
0
0
ES17-JAVA API文档管理

1.保存文档 可以通过json工具把java对象转换成json字符串进行保存,也可以通过内置的帮助类直接构建json格式 /** * 获取客户端 * * @return */public static TransportClie...

贾峰uk
27分钟前
0
0
Python代码规范和命名规范

前言 Python 学习之旅,先来看看 Python 的代码规范,让自己先有个意识,而且在往后的学习中慢慢养成习惯 一、简明概述 1、编码 如无特殊情况, 文件一律使用 UTF-8 编码 如无特殊情况, 文件头...

blackfoxya
29分钟前
0
0
联动滑动之一:NestScrollChild和NestedScrollingParent

NestScrollChild和NestedScrollingParent 吐槽一下开源中国竟然标题字数有限制 由于项目中使用了CoordinateLayout来解决联动以及实现炫酷的UI效果,那么必须就要研究一波源码了,毕竟知其然知...

JerryLin123
47分钟前
1
0
cloudera spark2.2 读写hbase

cloudera spark2.2 读写hbase 例子 host = 'bigdata-03,bigdata-05,bigdata-04'conf = { "hbase.zookeeper.quorum": host, "hbase.mapreduce.inputtable": "student1"}k......

osenlin
51分钟前
0
0
数据库规范化

转载自 一个小时学会MySQL数据库 地址:http://www.cnblogs.com/best/p/6517755.html 截取其中 1.4 部分 用于自己学习使用 感谢作者:张果 1.4、数据库规范化 经过一系列的步骤,我们现在终于...

十万猛虎下画山
52分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部