工作以后,发觉真的几乎没有像大学那样空闲的时间,坐下来看看书写写博客了。最近的一篇博客距离现在已经近一个多月了,最近也在复习Java的东西,准备校招,看了看JVM的东西,就当作记笔记。

(一)JVM参数:

  • 第一类包括了标准参数。顾名思义,标准参数中包括功能和输出的参数都是很稳定的,很可能在将来的 JVM 版本中不会改变。你可以用 java 命令(或者是用 java -help)检索出所有标准参数。我们在第一部分中已经见到过一些标准参数,例如:-server。
  • 第二类是 X 参数,非标准化的参数在将来的版本中可能会改变。所有的这类参数都以 - X 开始,并且可以用 java -X 来检索。注意,不能保证所有参数都可以被检索出来,其中就没有 - Xcomp。
  • 第三类是包含 XX 参数(到目前为止最多的),它们同样不是标准的,甚至很长一段时间内不被列出来(最近,这种情况有改变 ,我们将在本系列的第三部分中讨论它们)。然而,在实际情况中 X 参数和 XX 参数并没有什么不同。X 参数的功能是十分稳定的,然而很多 XX 参数仍在实验当中(主要是 JVM 的开发者用于 debugging 和调优 JVM 自身的实现)。

(1)-Xms20M

表示设置JVM启动内存的最小值为20M,必须以M为单位

(2)-Xmx20M

表示设置JVM启动内存的最大值为20M,必须以M为单位。将-Xmx和-Xms设置为一样可以避免JVM内存自动扩展。大的项目-Xmx和-Xms一般都要设置到10G、20G甚至还要高

(3)-verbose:gc

表示输出虚拟机中GC的详细情况

(4)-Xss128k

表示可以设置虚拟机栈的大小为128k

(5)-Xoss128k

表示设置本地方法栈的大小为128k。不过HotSpot并不区分虚拟机栈和本地方法栈,因此对于HotSpot来说这个参数是无效的

(6)-XX:PermSize=10M

表示JVM初始分配的永久代的容量,必须以M为单位

(7)-XX:MaxPermSize=10M

表示JVM允许分配的永久代的最大容量,必须以M为单位,大部分情况下这个参数默认为64M

(8)-Xnoclassgc

表示关闭JVM对类的垃圾回收

(9)-XX:+TraceClassLoading

表示查看类的加载信息

(10)-XX:+TraceClassUnLoading

表示查看类的卸载信息

(11)-XX:NewRatio=4

表示设置年轻代:老年代的大小比值为1:4,这意味着年轻代占整个堆的1/5

(12)-XX:SurvivorRatio=8

表示设置2个Survivor区:1个Eden区的大小比值为2:8,这意味着Survivor区占整个年轻代的1/5,这个参数默认为8

(13)-Xmn20M

表示设置年轻代的大小为20M

(14)-XX:+HeapDumpOnOutOfMemoryError

表示可以让虚拟机在出现内存溢出异常时Dump出当前的堆内存转储快照

(15)-XX:+UseG1GC

表示让JVM使用G1垃圾收集器

(16)-XX:+PrintGCDetails

表示在控制台上打印出GC具体细节

(17)-XX:+PrintGC

表示在控制台上打印出GC信息

(18)-XX:PretenureSizeThreshold=3145728

表示对象大于3145728(3M)时直接进入老年代分配,这里只能以字节作为单位

(19)-XX:MaxTenuringThreshold=1

表示对象年龄大于1,自动进入老年代

(20)-XX:CompileThreshold=1000

表示一个方法被调用1000次之后,会被认为是热点代码,并触发即时编译

(21)-XX:+PrintHeapAtGC

表示可以看到每次GC前后堆内存布局

(22)-XX:+PrintTLAB

表示可以看到TLAB的使用情况

(23)-XX:+UseSpining

开启自旋锁

(24)-XX:PreBlockSpin

更改自旋锁的自旋次数,使用这个参数必须先开启自旋锁

(二)用法实例:

 import java.util.Date;
import java.util.concurrent.TimeUnit; public class Main {
public static final int MB = 1024 * 1024;
public static void main(String[] args) throws InterruptedException { TimeUnit.SECONDS.sleep(20);
byte[] b1, b2, b3, b4;
b1 = new byte[2 * MB];
System.out.println("第一个2M分配完毕 time = " + new Date());
TimeUnit.SECONDS.sleep(5);
b2 = new byte[2 * MB];
System.out.println("第二个2M分配完毕 time = " + new Date());
TimeUnit.SECONDS.sleep(5);
b3 = new byte[2 * MB];
System.out.println("第三个2M分配完毕 time = " + new Date());
TimeUnit.SECONDS.sleep(5);
b4 = new byte[2 * MB];
System.out.println("第四个2M分配完毕 time = " + new Date());
TimeUnit.SECONDS.sleep(10);
}
}

JVM的参数设置如下:  -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8

Xms最小堆,Xmx最大堆都设置为了20M。Xmn年轻代设置为了10M,那么老年代也为10M,SurvivorRatio年轻带的Eden和Survivor的比值为8:1:1。

 [GC (Allocation Failure) [PSYoungGen: 8192K->1008K(9216K)] 8192K->1648K(19456K), 0.0012271 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 7446K->1016K(9216K)] 8086K->2352K(19456K), 0.0016344 secs] [Times: user=0.13 sys=0.00, real=0.00 secs]
第一个2M分配完毕 time = Sun Jul 29 16:00:40 CST 2018
第二个2M分配完毕 time = Sun Jul 29 16:00:45 CST 2018
第三个2M分配完毕 time = Sun Jul 29 16:00:50 CST 2018
[GC (Allocation Failure) [PSYoungGen: 8414K->1000K(9216K)] 9750K->8577K(19456K), 0.0065138 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC (Ergonomics) [PSYoungGen: 1000K->0K(9216K)] [ParOldGen: 7577K->8005K(10240K)] 8577K->8005K(19456K), [Metaspace: 9104K->8987K(1058816K)], 0.0158481 secs] [Times: user=0.13 sys=0.00, real=0.02 secs]
第四个2M分配完毕 time = Sun Jul 29 16:00:55 CST 2018
Heap
PSYoungGen total 9216K, used 2921K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 35% used [0x00000000ff600000,0x00000000ff8da738,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 8005K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 78% used [0x00000000fec00000,0x00000000ff3d15f8,0x00000000ff600000)
Metaspace used 9046K, capacity 9256K, committed 9600K, reserved 1058816K
class space used 1060K, capacity 1117K, committed 1152K, reserved 1048576K Process finished with exit code 0

分析如下:

第二,第三行可能是  TimeUnit.SECONDS.sleep(20); 这个占了内存,导致内存不足,然后就进行了两次年轻代GC,主要是为了看jconsole的那两幅图。

分配了三个2M以后,发觉eden区不够位置了,此时进行了年轻代的GC,但是 担保失败了 GC (Allocation Failure)。可能在老年代没有找到连续的内存,所以担保失败后,进行了一次full gc。

我们看jconsole上面的两幅图片,在16:01前面,Eden区突然下降,Old区突然上升。说明full gc将Eden区的三个2M的全部放到了Old区。然后将第四个2M的放到了Eden区。

所以最后,Eden区分配了一个b4,Old区分配了b1,b2,b3三个。看日志也可以看出来。

下来我们修改下参数,避免它进行full gc,毕竟full gc是不太好的。

-verbose:gc -Xms110M -Xmx110M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8

我们将老年代调到100M,你会发觉就不会进行full gc了,因为担保成功了。所以新生代,老年代最好的比列,并不是1:1,而是老年代站绝大多数,毕竟新生代 “死的快”。

最近接触到的JVM参数仅限于这几个,工具用的也就是jps,jconsole,不是特别的多。所以这里就举了一个例子出来。但这个例子的很好的说明了,如何避免Full GC

Full GC发生大概有以下几种情况:

1:老年代不足,比如上面的full gc。新生代的对象不能全部进入老年代,即担保失败,那么就行一次full gc。同理大对象直接进入老年代,也可能进行full gc

2:CMS垃圾回收器。CMS因为采用的标记清除算法,所以很容易产生大量的碎片,所以full gc特别容易。还有一种就是CMS是一种并发清理垃圾的,在并发清理的过程,有对象进入,但空间不足,也会造成一次full gc。可能通过调参来避免,比如调到老年代用到了90%,85%等进行cms收集来避免。

自己本人由于是学生,实战经验比较少,对JVM理解也不是特别的深入,如有错误,还希望各位大神能指出。大家一同学习进步。

JVM参数以及用法的更多相关文章

  1. JVM基础系列第14讲:JVM参数之GC日志配置

    说到 Java 虚拟机,不得不提的就是 Java 虚拟机的 GC(Garbage Collection)日志.而对于 GC 日志,我们不仅要学会看懂,而且要学会如何设置对应的 GC 日志参数.今天就让 ...

  2. java heap space解决方法和JVM参数设置

    在JVM中如果98%的时间是用于GC(Garbage Collection)且可用的 Heap size 不足2%的时候将抛出异常信息,java.lang.OutOfMemoryError: Java ...

  3. 查看JVM参数

    如何查看一个正在运行中的java程序,它的某个jvm参数是否开启?具体值是多少? jps jinfo jvm的参数类型: 1.标配参数:java -version  ,java -help , jav ...

  4. JVM参数概述

    标准参数(-) 所有的JVM实现都必须实现这些参数的功能,而且向后兼容. 通过命令 java 查看如下: 用法: java [-options] class [args...] (执行类) 或 jav ...

  5. Java 6 JVM参数选项大全(中文版)

    原文来自: http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm 本文是基于最新的SUN官方文档Java SE 6 Hotsp ...

  6. jinfo_动态调整JVM参数(无需重启)(实践)

    ​本文演示在JVM进程运行过程中动态开启/关闭 GC输出,无需重启JVM进程 jinfo使用介绍 可以用来查看正在运行的Java应用程序的扩展参数,甚至支持在运行时,修改部分参数 -flag < ...

  7. linux管道命令grep命令参数及用法详解---附使用案例|grep

    功能说明:查找文件里符合条件的字符串. 语 法:grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>] ...

  8. JVM参数OmitStackTraceInFastThrow:不打印NullPointerException异常堆栈

    查看线上日志,遇到一个诡异的问题,就是系统大量空指针的异常,但是没有打印堆栈,导致不方便定位问题. 经过一番代码调试,确定并非程序代码问题.没有线索之后,从Google找到了答案:是因为在server ...

  9. tomcat,zookeeper,activeMQ,Kafka设置jvm参数

    1,tomcat设置jvm参数 设置方法:   在tomcat bin 目录增加配置:setenv.sh   #add tomcat pid CATALINA_PID="$CATALINA_ ...

随机推荐

  1. JS基础-分支结构-循环-数组

    1.分支结构  1.if结构    语法:    if(条件){       语句块:    }    注意:      1.条件尽量是boolean的,如果不是boolean的,以下条件值,会当做f ...

  2. Linux 第十三天

    十五.shell编程 1.Shell是什么 1)Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动.挂起.停止甚至是编写一 ...

  3. MFC设置单文档保存格式以及标题

    在使用MFC编写单文档程序时,有时候需要将编辑的内容序列化为文件,使该文件可以直接以自己的程序打开,这时候需要在保存时将文件后缀改为我们想要的格式. 步骤 打开String Table,找到IDR_M ...

  4. hdmi中深度色彩像素打包

    4个色彩像素包模式:24- 30- 36- 48- 不同模式下tmds时钟与与像素的比是位宽与24的比值 . 24 bit mode: TMDS clock = 1.0 x pixel clock ( ...

  5. 【python-HTMLTestRunner】HTMLTestRunner测试报告中文乱码问题解决

    打开HTMLTestRunner.改动如图所示行 改成‘utf-8’

  6. ESP32作为接入点AP

    作为接入点的第一个任务是使用esp_wifi_set_mode()函数设置ESP32 函数并传递请求,作为接入点,可以把ESP32设置为AP或者APSTA,即 esp_wifi_set_mode(WI ...

  7. 7.AOP编程

    注解和xml混合使用 1.将所有的bean都配置xml中 <bean id="" class=""> 2.将所有的依赖都使用注解 @Autowire ...

  8. MVC身份验证及权限管理(转载)

    from https://www.cnblogs.com/asks/p/4372783.html MVC自带的ActionFilter 在Asp.Net WebForm的中要做到身份认证微软为我们提供 ...

  9. 背水一战 Windows 10 (72) - 控件(控件基类): UIElement - UIElement 的位置, UIElement 的布局, UIElement 的其他特性

    [源码下载] 背水一战 Windows 10 (72) - 控件(控件基类): UIElement - UIElement 的位置, UIElement 的布局, UIElement 的其他特性 作者 ...

  10. 剑指offer编程题Java实现——面试题8旋转数组的最小数字

    剑指offer面试题8:旋转数组的最小数字 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1, ...