JVM底层原理及调优

1.java虚拟机内存模型(JVM内存模型)

1.堆(-Xms -Xmx -Xmn)
java堆,也称为GC堆,是JVM中所管理的内存中最大的一块内存区域,是线程共享的,在JVM启动时创建。存放了对象的实例及数组(所有new的对象),
无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中;
2.线程栈
每个线程存在一个独立的线程栈内存区域,每个线程栈内存中会为每个方法创建各自的栈帧,栈帧中包含:局部变量表、操作数栈、动态链接、方法出口等;
栈中存放:方法调用过程中基本数据类型的变量(int、short、long、byte、float、double、boolean、char等)以及对象的引用变量;
其中64位长度的long和double类型的数据会占用两个局部变量的空间,其余数据类型只占一个;
3.方法区(元空间/永久代)
存放常量、静态变量、类信息、即时编译器后的代码,运行时常量池:方法区的一部分,Class文件中除了有类的版本,字段,方法,接口等描述信息外,
还有一项信息就是常量池,用于存放编译器生成的各种符号引用,这部分内容将在类加载后放到方法区的运行时常量池中,
元空间取代永久代,隔离堆和元空间的垃圾回收,避免频繁Full GC以及OOM等问题;
4.程序计数器
当前线程所执行的字节码的行号指示器,程序计数器的意义:
1.确保多线程程序的正常运行
2.java是多线程的,意味着线程存在上下文切换

2.GC的基础知识

2.1  什么是垃圾? 没有任何引用指向的一个对象或者多个对象(循环引用)

2.2 如何定位垃圾? 引用计数和roots可达性分析 (java使用的是根可达性分析算法)

在Java语言中,GC Roots包括:
线程栈变量
静态变量
常量池
JNI指针

2.3 GC垃圾回收算法比较

GC回收算法比较

特性

标记清除算法

位置分散,容易产生碎片

复制算法

浪费空间

标记压缩算法

效率低(适用老年代)

分代收集算法

算法搭配灵活(new-复制,old-标记压缩)

2.4 新生代 = Eden + 2个survivor区 new:old = 1: 2

2.5 新生代、老年代数据流转大致过程

新生代 = Eden + 2个survivor区
1. YGC回收之后,大多数的对象会被回收,活着的进入s0
2. 再次YGC,活着的对象eden + s0 -> s1
3. 再次YGC,eden + s1 -> s0
4. 年龄足够 -> 老年代 (15 CMS 6)
5. s区装不下 -> 老年代
老年代
1. 顽固分子
2. 老年代满了FGC Full GC
GC回收
1.尽量减少FGC
2 minorGC = YoungGC
3 majorGC = FullGC

Minor GC触发条件:当Eden区满时,触发Minor GC。

Full GC触发条件:

a.调用System.gc时,系统建议执行Full GC,但是不必然执行

b.老年代空间不足

c.方法去空间不足

d.通过Minor GC后进入老年代的平均大小大于老年代的可用内存

e.由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

2.6 常见的垃圾回收器

1. Serial 年轻代 串行回收 GC线程回收,其他线程暂停
2. PS 年轻代 并行回收
3. ParNew 年轻代 配合CMS的并行回收 Serial收集器新生代的并行版本
4. SerialOld
5. ParallelOld
6. ConcurrentMarkSweep(CMS) 老年代 并发的, 垃圾回收和应用程序同时运行,降低STW的时间(200ms)
CMS问题较多,一般都需要手动指定。CMS采用标记清除算法回收,所以就会存在产生碎片的问题,当老年代分配的对象分配不下的情况,需要配合SerialOld进行老年代的回收
7. G1(10ms)
8. ZGC (1ms) 相当于 C++
9. Shenandoah
10.Eplison

1.8默认的垃圾回收:PS + ParallelOld

3.GC调优准备

3.1 了解生产环境下的垃圾回收器组合 打印JVM内存信息 java -XX:+PrintCommandLineFlags

3.2  JVM的命令行参数参考:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

* JVM参数分类
> 标准: - 开头,所有的HotSpot都支持
> 非标准:-X 开头,特定版本HotSpot支持特定命令
> 不稳定:-XX 开头,下个版本可能取消

1. java -XX:+PrintCommandLineFlags
2. java -Xmn10M -Xms40M -Xmx60M -XX:+PrintCommandLineFlags
3. java -XX:+UseConcMarkSweepGC -XX:+PrintCommandLineFlags
4. java -XX:+PrintFlagsInitial 默认参数值
5. java -XX:+PrintFlagsFinal 最终参数值
6. java -XX:+PrintFlagsFinal | grep xxx 找到对应的参数
7. java -XX:+PrintFlagsFinal -version |grep GC

* 常见垃圾回收器组合参数设定:(1.8)
* -XX:+UseSerialGC = Serial New (DefNew) + Serial Old
* 小型程序。默认情况下不会是这种选项,HotSpot会根据计算及配置和JDK版本自动选择收集器
* -XX:+UseParNewGC = ParNew + SerialOld
* 这个组合已经很少用(在某些版本中已经废弃)
* https://stackoverflow.com/questions/34962257/why-remove-support-for-parnewserialold-anddefnewcms-in-the-future
* UseConcMarkSweepGC = ParNew + CMS + Serial Old
* UseParallelGC = Parallel Scavenge + Parallel Old (1.8默认) 【PS + SerialOld】
* UseParallelOldGC = Parallel Scavenge + Parallel Old
* UseG1GC = G1

常用的GC组合

参数

描述

UseSerialGC

Serial New+ Serial Old

UseParNewGC

ParNew+Serial Old(rarely dispose)

UseConcMarkSweepGC

ParNew+CMS+Serial Old

UseParallelGC/UseParallelOldGC

Parallel Scavenge+Parallel Old(1.8默认)

UseG1GC

G1

2.3 JVM调优的步骤

* 步骤:
. 熟悉业务场景(没有最好的垃圾回收器,只有最合适的垃圾回收器)
. 响应时间、停顿时间
. 吞吐量 = 用户时间 / 用户时间 + GC时间
响应时间和吞吐量无法同时调优 响应时间快 == GC停顿时间短
. 选择回收器组合
. 计算内存需求
. 设定年代大小、升级年龄
. 设定日志参数
. -Xloggc:/opt/xxx/logs/xxx-xxx-gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles= -XX:GCLogFileSize=20M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCCause
. 观察日志情况

4.GC日志查看

通过在java命令种加入参数来指定对应的gc类型,打印gc日志信息并输出至文件等策略

java -XX:+PrintGCDateStamaps -XX:+PrintGCDetails GCTest
-XX:+PrintGC 输出GC日志
-XX:+PrintGCDetails 输出GC的详细日志
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 --04T21::59.234+)
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径

2019-11-19T11:50:42.352+0800[当前时间戳]: 0.169[时间戳]: [GC[Young GC (Allocation Failure) [PSYoungGen: 63744K[回收前年轻代大小]->9680K[回收后年轻代大小](74240K)总年轻代大小] 63744K回收前堆大小->62928K回收后堆大小(243712K分配堆的总大小), 0.0092841【消耗总时间】 secs] [Times: user=0.02【用户花费时间】 sys=0.03【系统花费时间】,real =0.01 secs [总消耗时间]】

2019-11-19T11:50:42.369+0800: 0.186: [GC (Allocation Failure) [PSYoungGen: 73412K->9728K(138240K)] 126661K->126473K(307712K), 0.0106607 secs [Times: user=0.03 sys=0.03, real=0.01 secs】

2019-11-19T11:50:43.326+0800: 1.142: [Full GC (Ergonomics) [PSYoungGen: 798012K->797708K(808960K)] [ParOldGen: 2708855K->2708855K(2708992K)] 3506867K->3506564K(3517952K), [Metaspace: 2735K->2735K(1056768K)], 0.0182299 secs] [Times: user=0.04 sys=0.00, real=0.02 secs]

2019-11-19T11:50:43.344+0800: 1.160: [Full GC (Allocation Failure) [PSYoungGen: 797708K->797708K(808960K)] [ParOldGen: 2708855K->2708844K(2708992K)] 3506564K->3506552K(3517952K), [Metaspace: 2735K->2735K(1056768K)], 0.6587112 secs] [Times: user=6.22 sys=0.02, real=0.66 secs]

Heap
PSYoungGen total 808960K, used 798720K [0x000000076d580000【起始地址】, 0x000000079fa00000【占用空间结束地址】, 0x00000007c0000000【整体空间结束地址】)
eden space 798720K, 100% used [0x000000076d580000,0x000000079e180000,0x000000079e180000)
from space 10240K, 0% used [0x000000079eb00000,0x000000079eb00000,0x000000079f500000)
to space 9728K, 0% used [0x000000079e180000,0x000000079e180000,0x000000079eb00000)
ParOldGen total 2708992K, used 2708845K [0x00000006c8000000, 0x000000076d580000, 0x000000076d580000)
object space 2708992K, 99% used [0x00000006c8000000,0x000000076d55b440,0x000000076d580000)
Metaspace used 2770K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 264K, capacity 386K, committed 512K, reserved 1048576K

JVM底层原理及调优之笔记一的更多相关文章

  1. JDK记录-JVM原理与调优(转载)

    转载自<https://www.cnblogs.com/andy-zhou/p/5327288.html> 一.什么是JVM JVM是Java Virtual Machine(Java虚拟 ...

  2. Java 面试题 三 <JavaWeb应用调优线程池 JVM原理及调优>

    1.Java Web应用调优线程池 不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文由浅入深,介 ...

  3. 深入理解JVM虚拟机10:JVM常用参数以及调优实践

    转自http://www.rowkey.me/blog/2016/11/02/java-profile/?hmsr=toutiao.io&utm_medium=toutiao.io&u ...

  4. SQL运行内幕:从执行原理看调优的本质

    相信大家看过无数的MySQL调优经验贴了,会告诉你各种调优手段,如: 避免 select *: join字段走索引: 慎用in和not in,用exists取代in: 避免在where子句中对字段进行 ...

  5. [Spark性能调优] 第一章:性能调优的本质、Spark资源使用原理和调优要点分析

    本課主題 大数据性能调优的本质 Spark 性能调优要点分析 Spark 资源使用原理流程 Spark 资源调优最佳实战 Spark 更高性能的算子 引言 我们谈大数据性能调优,到底在谈什么,它的本质 ...

  6. 一文读懂Java GC原理和调优

    概述 本文介绍GC基础原理和理论,GC调优方法思路和方法,基于Hotspot jdk1.8,学习之后将了解如何对生产系统出现的GC问题进行排查解决 阅读时长约30分钟,内容主要如下: GC基础原理,涉 ...

  7. 老大难的GC原理及调优,这下全说清楚了

    概述 本文介绍GC基础原理和理论,GC调优方法思路和方法,基于Hotspot jdk1.8,学习之后将了解如何对生产系统出现的GC问题进行排查解决 阅读时长约30分钟,内容主要如下: GC基础原理,涉 ...

  8. JVM基本配置与调优

    JVM基本配置与调优 JVM调优,一般都是针对堆内存配置调优. 如图:堆内存分新生代和老年代,新生代又划分为eden区.from区.to区. 一.区域释义 JVM内存模型,堆内存代划分为新生代和老年代 ...

  9. 艾编程coding老师:深入JVM底层原理与性能调优

    1. Java内存模型JMM,内存泄漏及解决方法:2. JVM内存划分:New.Tenured.Perm:3. 垃圾回收算法:Serial算法.并行算法.并发算法:4. JVM性能调优,CPU负载不足 ...

随机推荐

  1. Javase之集合体系(2)之List及其子类ArrayList,LinkedList与Vector及其迭代器知识

    集合体系之List及其子类ArrayList,LinkedList与Vector及其迭代器知识 List(接口) 特点:有序(存储与取出顺序相同),可重复 List子类特点: ​ ArrayList: ...

  2. 备战双十一,腾讯WeTest有高招——小程序质量优化必读

    WeTest 导读 2018年双十一战场小程序购物通道表现不俗,已逐渐成为各大品牌方角逐的新战场.数据显示,截止目前95%的电商平台都已经上线了小程序.除了电商企业外,许多传统线下商家也开始重视小程序 ...

  3. ADB控制手机命令(adb命令)

    手机端配置tcp方式连接 su setprop service.adb.tcp.port 5555 stop adbd start adbd 首先使用管理员权限,然后打开监听5555端口 电脑端使用a ...

  4. [视频教程] 基于redis的消息队列实现与思考

    使用redis的list列表来实现消息队列功能,相信大家都听过消息队列,但是在业务中可能并没有真正去使用它.在公司项目中正好有个场景使用到了消息队列,因此就来说一下流程.在web界面上有个功能是群发邮 ...

  5. 基于tiny4412的Linux内核移植 --- aliases节点解析【转】

    转自:https://www.cnblogs.com/pengdonglin137/p/5252348.html 阅读目录(Content) 作者信息 平台简介 正文 回到顶部(go to top) ...

  6. spring框架开发包官网各版本的下载地址

    链接地址https://spring.io/tools3/sts/legacy,推荐迅雷下载

  7. linux下C/C++编译时系统搜索 include 和 链接库 文件路径的指定

     C/C++程序在linux下被编译和连接时,GCC/G++会查找系统默认的include和link的路径,以及自己在编译命令中指定的路径.自己指定的路径就不说了,这里说明一下系统自动搜索的路径.   ...

  8. windows server2008 R2下mysql 5.7版本中修改编码为utf-8的方法步骤

    首先通过 show variables like 'character_set_%'; 查看mysql字符集情 默认编码为 latin1 然后关闭数据库 在mysql安装目录下找到my.ini文件 在 ...

  9. 用java写爬虫

    今天学了怎么用java代码获取要爬取页面的源代码,因为只写了一点,所以接下来会陆续跟新此文章 首先,看一下我写的代码 这就是爬取下来的网页源代码,第一张图刚刚补注释有个注释写错了,别误导你们就行,接下 ...

  10. 用 FFLIB 实现 Apex 企业设计模式

    Apex 企业设计模式将应用分为服务层.模型层.选择逻辑层.工作单元几个部分.FFLIB 是一个开源的 Apex 框架,可以帮助开发者快速建立相关的功能. FFLIB 的安装 FFLIB 可以直接部署 ...