文档章节

JVM 垃圾回收器与参数配置

秋风醉了
 秋风醉了
发布于 2017/09/06 18:27
字数 2437
阅读 93
收藏 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==========

© 著作权归作者所有

共有 人打赏支持
秋风醉了
粉丝 241
博文 566
码字总数 417296
作品 0
朝阳
程序员
私信 提问
Java GC系列:Java垃圾回收详解

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

满风
2015/04/10
0
0
JVM系列第9讲:JVM垃圾回收器

前面文章中,我们介绍了 Java 虚拟机的内存结构,Java 虚拟机的垃圾回收机制,那么这篇文章我们说说具体执行垃圾回收的垃圾回收器。 总的来说,Java 虚拟机的垃圾回收器可以分为四大类别:串...

陈树义
2018/11/22
0
0
Java虚拟机(JVM)(自动内存管理机制)

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

亚特兰缇斯
2015/03/05
0
0
JVM性能调优1:JVM性能调优理论及实践(收集整理)

本系列包括: JVM性能调优1:JVM性能调优理论及实践(收集整理) JVM性能调优2:JVM性能调优参数整理 JVM性能调优3:JVM堆溢出分析过程和命令 JVm性能调优4:GC日志分析 JVM性能调优5:Heap堆...

morpheusWB
2018/09/08
0
0
Java的垃圾回收之算法[转]

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

kext
2012/03/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

2019-1-16

2019-1-16 星期三 晴转霾 早饭:小面包+鸡蛋糕;午饭:馍+地三鲜;晚饭:; 6:50起床,因为媳妇说可能今天晚上去大雁塔那边吃饭,早上起来后洗了个澡(主要因为头发很油了)。 今天早上天气...

莱菔籽
15分钟前
0
0
localDate、localDateTime、localTime的使用

从前端接受的时候,localDate类型的数据要转换,加 @DateTimeFormat(pattern = "yyyy-MM-dd")

shimmerkaiye
22分钟前
1
0
1.二叉树

概念 二叉树(binary tree)是每个节点最多只有两个分支(即不存在分支度大于2的节点)的结构树。通常分支被称为“左子树”和“右子树”,左子树和右子树的位置不能随意颠倒。二叉树的第i层 ...

火拳-艾斯
25分钟前
2
0
java 线程

一、通过实现Runnable接口来创建线程 public class TestThread implements Runnable { public void run() { try { for (int i = 0; i < 10; i++) { ......

朝如青丝暮成雪
31分钟前
1
0
关于eclipse2017 import javax.servlet.jsp.tagext引入错误得问题

在eclipse中: 这个javax.servlet.jsp.tagext属于是tomcat相关jar包找到jsp-api.jar 在tomcat文件夹下边的lib文件夹中就有 如果项目中报错的话 把这个加入到项目中 在myeclipse中: 如下图,...

ZhangLG
45分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部