jdk1.8——jvm分析与调优
很多文章都是讲如何配置JVM各个参数的,但是生产环境里参数的值到底配置为多少,却没有一个具体的指标。文章分四个部分,分别是JVM说明、配置,GC的过程和具体配置值。
一.JVM空间说明
- JDK 1.7及以前,Java 类信息、常量池、静态变量都存储在 Perm(永久代)里。类的元数据和静态变量在类加载的时候分配到 Perm,当类被卸载的时候垃圾收集器从 Perm 处理掉。 
- JDK 1.8 的对 JVM 架构的改造将类元数据放到本地内存中,另外,将常量池和静态变量放到 Java 堆里。HotSopt VM 将会为类的元数据明确分配和释放本地内存。在这种架构下,类元信息就突破了原来 -XX:MaxPermSize 的限制,所以PermSize的配置也是无效的,现在可以使用更多的本地内存。这样就从一定程度上解决了原来在运行时生成大量类的造成经常 Full GC 问题,如运行时使用反射、代理等 

干货:可以发现最明显的一个变化是元空间从虚拟机转移到本地内存;默认情况下,元空间的大小仅受本地内存的限制。这意味着以后不会因为永久代空间不够而抛出OOM异常了。
jdk1.8以前版本的class和jar包数据存储在permGen下面 ,permGen大小是固定的,而且项目之间无法共用公有的class,所以很容易碰到OOM异常。
改成metaSpaces后,各个项目会共享同样的class内存空间,比如多个项目都引用了apache-common包,在metaSpaces中只会存储一份apache-common的class,提高了内存的利用率,垃圾回收更有效率。
二.JVM参数配置
- 在jdk1.8以前,生产环境一般有如下配置
-XX:PermSize=512M -XX:MaxPermSize=1024M
表示在JVM里存储Java类信息,常量池和静态变量的永久代区域初始大小为512M,最大为1024M。在项目启动后,这个值是固定的,如果项目class过多,很可能遇到OutOfMemoryError: PermGen异常。
- 升级JDK1.8之后,上面的perm配置已经变成
-XX:MetaspaceSize=512M XX:MaxMetaspaceSize=1024M
MetaspaceSize如果不做配置,通过jinfo查看默认MetaspaceSize大小(约21M),MaxMetaspaceSize很大很大,前面说过MetaSpace只受本地内存大小限制。
jinfo -flag MetaspaceSize 1234  #结果为:-XX:MetaspaceSize=21807104
jinfo -flag MaxMetaspaceSize 1234 #结果为:-XX:MaxMetaspaceSize=18446744073709547520
干货:MetaspaceSize为出发FullGC的阈值,默认约为21M,如做了配置,最小阈值为自定义配置大小。空间使用达到阈值,触发FullGC,同时对该值扩大。当然如果元空间实际使用小于阈值,在GC的时候也会对该值缩小。
MaxMetaspaceSize为元空间的最大值,如果设置太小,可能会导致频繁FullGC,甚至OOM。
三.GC(GarbageCollection)过程
首先贴一张网上盗来的大图,用它来说明下GC的过程再合适不过。

- 新new的对象都放在Eden区(伊甸园嘛,创造的地方)
- Eden区满或者快满的时候进行一次清理(Minor Gc),不被引用的对象直接被干掉;还有引用的对象,但是年龄比较大的,挪到S0区
- 下次Eden区快满的时候,会进行上一步的操作,并且将Eden和S0区的年纪大的对象放到S1区【原理上随时保持S0和S1有一个是空的,用来存下一次的对象】
- 下下次,Eden区快满的时候,会进行上一步操作,并且将Eden和S1区的年纪大的对象放到S0区【此时S1区就是空的】
- 直到Eden区快满,S0或者S1也快满的时候,这时候就把这两个区的年纪大的对象放到Old区
- 依次循环,直到Old区也快满的时候,Eden区也快满的时候,会对整个这一块内存区域进行一次大清洗(FullGC),腾出内存,为之后的对象创建,程序运行腾地方。
清理Eden区和Survivor区叫Minor GC;清理Old区叫Major GC;清理整个堆空间—包括年轻代和老年代叫Full GC。
四. JVM参数配置指南
前面三个部分对JVM进行了整体的了解,接下来是本文的重点。
-XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=256M -Xms256m -Xmx256m
文章看下来上面这段配置的意思很简单,设置元空间的初始值和最大值,设置堆空间的初始值和最大值。
为什么MetaspaceSize要设置为128M?为什么堆内存初始值Xms设置为256M而不是512M?
按照Java官方的指导

- Java堆大小设置,Xms 和 Xmx设置为老年代存活对象的3-4倍,即FullGC之后的老年代内存占用的3-4倍永久代 PermSize和MaxPermSize(元空间)设置为老年代存活对象的1.2-1.5倍。
 年轻代Xmn的设置为老年代存活对象的1-1.5倍。
 老年代的内存大小设置为老年代存活对象的2-3倍。
可以让系统运行一段时间后查看系统的各个指标,然后在进行配置。如下用jstat工具查看jvm的情况
jstat -gc 12345
###
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
13824.0 22528.0 13377.0  0.0   548864.0 535257.2  113152.0   46189.3   73984.0 71119.8 9728.0 9196.2     14    0.259   3      0.287    0.546
OU表示老年代所占用的内存为 46189.3 K(大约45M);那么jvm相应的配置参数应该做如下修改
-XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=64M -Xms180m -Xmx180mjdk1.8——jvm分析与调优的更多相关文章
- 网络摘抄jdk1.8——jvm分析与调优
		一.JVM空间说明 JDK 1.7及以前,Java 类信息.常量池.静态变量都存储在 Perm(永久代)里.类的元数据和静态变量在类加载的时候分配到 Perm,当类被卸载的时候垃圾收集器从 Perm ... 
- Java系列笔记(4) - JVM监控与调优
		目录 参数设置收集器搭配启动内存分配监控工具和方法调优方法调优实例 光说不练假把式,学习Java GC机制的目的是为了实用,也就是为了在JVM出现问题时分析原因并解决之.通过学习,我觉得JVM ... 
- JVM监控与调优
		目录 参数设置收集器搭配启动内存分配监控工具和方法调优方法调优实例 转:http://www.cnblogs.com/zhguang/p/java-jvm-gc.html光说不练假把式,学习J ... 
- [java] JVM监控与调优
		原文出处:http://www.cnblogs.com/zhguang/p/java-jvm-gc.html 光说不练假把式,学习Java GC机制的目的是为了实用,也就是为了在JVM出现问题时分 ... 
- Tomcat性能调优-JVM监控与调优
		参数设置 在Java虚拟机的参数中,有3种表示方法用"ps -ef |grep "java"命令,可以得到当前Java进程的所有启动参数和配置参数: 标准参数(-),所有 ... 
- 深入理解java:1.3.2 JVM监控与调优
		学习Java GC机制的目的是为了实用,也就是为了在JVM出现问题时分析原因并解决之. 本篇,来看看[ 如何监控和优化GC机制.] 通过学习,我觉得JVM监控与调优,主要在3个着眼点上: 1,如何配置 ... 
- Java系列笔记(4) - JVM监控与调优【转】
		Java系列笔记(4) - JVM监控与调优[转] 目录 参数设置收集器搭配启动内存分配监控工具和方法调优方法调优实例 光说不练假把式,学习Java GC机制的目的是为了实用,也就是为了在 ... 
- [JVM教程与调优] 了解JVM 堆内存溢出以及非堆内存溢出
		在上一章中我们介绍了JVM运行时参数以及jstat指令相关内容:[JVM教程与调优] 什么是JVM运行时参数?.下面我们来介绍一下jmap+MAT内存溢出. 首先我们来介绍一下下JVM的内存结构. J ... 
- 软件性能测试分析与调优实践之路-Java应用程序的性能分析与调优-手稿节选
		Java编程语言自从诞生起,就成为了一门非常流行的编程语言,覆盖了互联网.安卓应用.后端应用.大数据等很多技术领域,因此Java应用程序的性能分析和调优也是一门非常重要的课题.Java应用程序的性能直 ... 
随机推荐
- windows7 安装 docker-compose
			这篇博客,默认你已经安装了docker,下面介绍如何安装docker-compose 1.访问docker-compose的git地址 2.找到最新版的docker-compose 3.打开Docke ... 
- Java选择结构和循环结构
			1.选择结构 ①.ifif(){ } if(){}else{} if(){}else if(){}else if(){}else{} ②.switch switch (表达式) { case 常量 1 ... 
- ubuntu18 docker中部署ELK
			ELK是ElasticSearch.Logstash.Kibana的简称,一般用于日志系统,从日志收集,日志转储,日志展示等入手,用以提供简洁高效的日志处理机制. 鉴于没有额外的机器,这里就用dock ... 
- tornado利用装饰器记录每个http请求
			python利用装饰器记录每个http请求 设置装饰器 from functools import wraps from datetime import datetime ""&q ... 
- Django(二)模板
			一.模板概念 1.Django通过模板动态生成html 2.模板的加载位置 模板一般建立在templates文件夹中,全局路径的设置在settings.py中  DIRS:决定了整个项目的模板路径的 ... 
- k8s+jenkins(DevOps全流程)
			k8s集群搭建是参照别人的,链接找不到了.需要5台机器,3主2从,主最少搭建3台才能实现高可用. 流程jenkins打包代码 >> 把打包代码生成镜像 >> 备份镜像库旧镜像 ... 
- C# 从注册表判断指定ocx控件是否已注册 以及获取它的注册路径
			/// <summary> /// 注册控件 /// </summary> /// <returns></returns> public bool Re ... 
- PAT 1003我要通过!
			PAT 1003 我要通过! 答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的"答案正确"大派送 -- 只要读入的字符串满足下列条件,系统就输出&qu ... 
- 28、IE报vuex requires a Promise polyfill in this browser问题解决
			解决方法第一步: 安装 babel-polyfill . babel-polyfill可以模拟ES6使用的环境,可以使用ES6的所有新方法 npm install --save babel-polyf ... 
- XML简述
			XML简述 本文主要内容都是在中国大学MOOC上学习的,这里做个记录. 课程:Java核心技术(进阶),华东师范大学 陈良育老师 感谢陈良育老师,在他的慕课上受益匪浅. XML基本概念 XML(eXt ... 
