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. python web框架Flask——后台登录

    项目搭建 创建一个项目之后,需要在手动创建几个包(含有__init__.py文件的目录)和文件 1.在主目录下创建配置文件:config.py 2.在主目录下创建扩展文件:exts.py 3.在主目录 ...

  2. centos7中python3.6报错ModuleNotFoundError: No module named '_ssl' 或者 Max retries exceeded with url: / (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.",))

    如果在运行爬虫时报此错:requests.exceptions.SSLError: HTTPSConnectionPool(host='www.baidu.com', port=443): Max r ...

  3. 新MySQL查询和删除重复记录

    在工作中,我们经常会发现表中会存在重复数据,那么如何找出和删除这些数据呢? 下面,以一个小例子来说明: 1.创建学生表 1 CREATE TABLE student( 2 id INT PRIMARY ...

  4. Mysql—数据库管理与表管理

    数据库管理 表管理 删除表

  5. 爬虫---lxml简单操作

    前几篇写了一些Beautiful Soup的一些简单操作,也拿出来了一些实例进行实践,今天引入一个新的python库lxmt,lxmt也可以完成数据的爬取哦 什么是lxml lxml是python的一 ...

  6. Spring熔断

    Hystrix不再维护,使用Resilience4j来代替.

  7. ubuntu系统中查看python模块的源码

    案例:查看multiprocessing模块源码 1. 进入交互模式,导入模块,以multiprocessing模块为例 2. 查看multiprocessing.__file__属性,找到该模块的源 ...

  8. django内容回顾:

    Django 下载安装 命令行 pip install django==1.11.26 -i 源 pycharm 创建项目 命令行 django-admin startproject 项目名 pych ...

  9. 【Spring AOP】AOP实现原理(六)

    原文链接:https://my.oschina.net/guangshan/blog/1797461

  10. LG4556 [Vani有约会]雨天的尾巴 动态开点线段树+线段树合并

    问题描述 LG4556 题解 对于每一个结点,建立一棵动态开点线段树. 然后自低向上合并线段树. 同时维护整个值域的最大值和最大值位置. \(\mathrm{Code}\) #include<b ...