JVM

一、     jvm的加载流程及内存模型

每一个线程都有自己的程序计数器、都有自己的native方法,jvm栈,比如Student  student1 = new Strudent();student1是私有的。引用是私有的放在栈里面。new Strudent()是公有的,放在堆里面,因为多个引用可以对应一个对象。Gc回收的是内存,

 

jemalloc算法 jvm算法_jemalloc算法

jemalloc算法 jvm算法_jemalloc算法_02

二、     栈帧

想到方法。

先入后出

包含三部分:

1)局部变量表,

包括方法入参和局部变量。

2)操作数栈

保存计算过程中的中间结果和临时存储空间

3)帧数据区

  ① 常量池指针

  ② 异常处理表

  ③正常方法返回值

源空间就是方法去

 

jemalloc算法 jvm算法_JVM_03

三、     JVM垃圾回收算法

主动加载的几种方式

1)            new Student();

2)            反射的方式class ---构造器(有参和无参)--实例化对象

3)            Clone()

4)            子类初始化时,优先初始化父类

5)            调用静态方法

           符号引用和直接应用

           Java –V Student

           直接引用,是直接引用对象

1、垃圾回收算法

1)什么是垃圾回收

GC: 垃圾回收, 即: Garbage Collection。
垃圾: 特指存在于内存中的、 不会再被使用的对象。也就是失去引用。
回收: 清除内存中的“垃圾”对象。

 

jemalloc算法 jvm算法_jemalloc算法_04

2)垃圾回收的主要算法

 

jemalloc算法 jvm算法_JVM_05

①引用计数法

对于一个对象A, 只要有任何一个对象引用了A, 则A的引用计数器就加1,
当引用失效时, 引用计数器就减1.只要对象A的引用计数器的值为0, 则对
象A就不可能再被使用。
但引用计数器有两个严重问题:

(1)            无法处理循环引用的情况。
(2) 引用计数器要求在每次因引用产生和消除的时候, 需要伴随一个加减法操作, 对系统性能会有一定的影响。
因此: JVM并未选择此算法作为垃圾回收算法。

      ② 标记清除法

       标记清除算法是现代垃圾回收算法的基础,分为两个阶段:标记阶段和清除阶段。标记清除算法产生的最大问题就是空间碎片问题。

 

jemalloc算法 jvm算法_jemalloc算法_06

③ 复制算法

将原有内存空间分为两块。 每次只使用其中一块内存, 例如: A内存,

GC时将存活的对象复制到B内存中。 然后清除掉A内存所有对象。 开始使
用B内存。
复制算法没有内存碎片, 并且如果垃圾对象很多, 那么这种算法效率很高。
但是它的缺点是系统内存只能使用1/2。

 

jemalloc算法 jvm算法_jemalloc算法_07

Jvm中的应用:

新生代和老年代

新new一个对象在新生代,

以下三种情况进入老年代:

1>当8次gc还存活的情况下变为老年代;2> Bigobject; 3>S0空间不足

因为新生代大多对象都是“朝不保夕”, 所以在新生代串行GC中, 使用了复制算法。

 

jemalloc算法 jvm算法_老年代_08

④ 标记压缩算法

 老年代的回收算法

标记压缩算法是一种老年代的回收算法。它首先标记存活的对象, 然后将所有存活的对象压缩到内存的一端, 然后在清理所有存活对象之外的空间。
该算法不会产生内存碎片, 并且也不用将内存一分为二。 因此, 其性价比比较高。

 

jemalloc算法 jvm算法_JVM_09

⑤ 分代算法

将堆空间划分为新生代和老年代, 根据它们直接的不同特点, 执行不同的回收算法, 提升回收效率。

 

jemalloc算法 jvm算法_老年代_10

⑥ 分区算法

将堆空间划分成连续的不同小区间, 每个区间独立使用、 回收。 由于当堆空间大时, 一次GC的时间会非常耗时, 那么可以控制每次回收多少个小区间, 而不是整个堆空间,从而减少一次GC所产生的停顿。

回收哪一个不回收哪一个,正常情况下采用的是比例。

四、JVM垃圾收集器

1、串行回收器

串行回收器的特点:
1>只使用单线程进行GC
2>独占式的GC

 

jemalloc算法 jvm算法_jemalloc算法_11

串行收集器是JVM Client模式下默认的垃圾收集器

jemalloc算法 jvm算法_jemalloc算法_12

2、并行回收器 - P a r N e w & P a r a l l e l G C & P a r a l l e l O l d G C

将串行回收器多线程化。与串行回收器有相同的回收策略、算法、 参数。

 

jemalloc算法 jvm算法_jemalloc算法_13

 

jemalloc算法 jvm算法_jemalloc算法_14

3、并行回收器 CMS

Cms垃圾回收器的步骤

 

jemalloc算法 jvm算法_java_15

初始标记:找根节点

并发标记:顺着根节点,标记所有对象;

预清理:可以不去执行,做一个预判,下一gc的时间和现在gc的时间会不会重叠,如果重叠减少一次停顿时间

重新标记:进行修正

并发清理:

4、收集器参数

 

jemalloc算法 jvm算法_jemalloc算法_16

 

5、G 1 的 G C 收 集 过 程

G1全称Garbage First Garbage Collector。 优先回收垃圾比例最高的区域。
G1收集器将堆划分为多个区域, 每次收集部分区域来减少GC产生的停顿时间。

 

jemalloc算法 jvm算法_java_17

1)      G1新生代

 

jemalloc算法 jvm算法_JVM_18

2)G1标记并发周期

需要三次stop the word

初始标记:标记根阶段 stop the word

根区域扫描:因为G1 新生代回收,有一部分可以到达老年代,所以需要进行一次根节点扫描

并发标记:扫描堆里面的存活对象

重新标记:最后一次修正 stop the word

独占清理:stop the word,计算存活的对象,计算gc的比例

 

jemalloc算法 jvm算法_jemalloc算法_19

3)G 1 — — 混 合 收 集

  这三个阶段是一个循环的过程。

 

jemalloc算法 jvm算法_老年代_20

 

jemalloc算法 jvm算法_老年代_21

 

jemalloc算法 jvm算法_jemalloc算法_22

四、     JVM常用参数

jemalloc算法 jvm算法_java_23

 

 

jemalloc算法 jvm算法_jemalloc算法_24

五、     JVM监控优化

1、          性能监控工具

 

jemalloc算法 jvm算法_java_25

1)    top命令

能够实时显示系统中各个进程的资源占用情况。
分为两部分: 系统统计信息&进程信息。

Line1:任务队列信息, 从左到右依次表示: 系统
当前时间、 系统运行时间、 当前登录用户数。
Load average表示系统的平均负载, 即任务队
列的平均长度——1分钟、 5分钟、 15分钟到现
在的平均值。
Line2:进程统计信息, 分别是: 正在运行进程数、睡眠进程数、 停止的进程数、 僵尸进程数。
Line3:CPU统计信息。 us表示用户空间CPU占用率、sy表示内核空间CPU占用率、 ni表示用户进程空间改变过优先级的进程CPU占用率。 id表示空闲CPU占用率、 wa表示待输入输出的CPU时间百分比、 hi表示硬件中断请求、 si表示软件中断请求。
Line4:内存统计信息。 从左到右依次表示: 物理内存总量、 已使用的物理内存、 空闲物理内存、内核缓冲使用量。
Line5:从左到右表示: 交换区总量、 已使用交换区大小、 空闲交换区大小、 缓冲交换区大小

 

jemalloc算法 jvm算法_java_26

 

2)vmstat

性能监测工具, 显示单位均为kb。 它可以统计CPU、 内存使用情况、 swap使用情况等信息, 也可以指定采样周期和采用次数。 例如: 每秒采样一次, 共计3次。

 

jemalloc算法 jvm算法_java_27

 procs列: r表示等待运行的进程数。 b表示处于非中断睡眠状态的进程数。

memory列: swpd表示虚拟内存使用情况。 free表示空闲内存量。 buff表示被用来作为缓存的内存。
swap列: si表示从磁盘交换到内存的交换页数量。 so表示从内存交换到磁盘的交换页数量。
io列: bi表示发送到块设备的块数, 单位: 块/秒。 bo表示从块设备接收到的块数。
system列: in表示每秒的中断数, 包括时钟中断。 cs表示每秒的上下文切换次数。
cpu列: us表示用户cpu使用时间。 sy表示内核cpu系统使用时间。 id表示空闲时间。
wa表示等待io时间

2)   iostat

可以提供详尽的I/O信息。

jemalloc算法 jvm算法_jemalloc算法_28

 如果只看磁盘信息, 可以使用-d参数。 即: Iostat –d 1 3 (每1秒采集一次持续3次)

tps列表示该设备每秒的传输次数。
Blk_read/s列表示每秒读取块数。
Blk_wrtn/s列表示每秒写入块数。
Blk_read列表示读取块数总量。
Blk_wrtn列表示写入块数总量。

Jdk工具:

1)       jps(比较常用)

用于列出java进程。执行语法:jps [-options]

Jps 列出java 进程id和类名

jps –q 仅列出java进程id
91275
jps –m 输出java进程的入参
91730 FireIOTest a b
jps –l 输出主函数的完整路径
91730 day1.FireIOTest
jps –v 显示传递给JVM的参数
91730 FireIOTest -Xmx512m -XX:+PrintGC -javaagent:/Applications/IntelliJ
IDEA.app/Contents/lib/idea_rt.jar=51673:/Applications/IntelliJ IDEA.app/Contents/bin -
Dfile.encoding=UTF-8

2)J D K 工 具 — — j s t a t

用于查看堆中的运行信息

执行语法: jstat –help jstat -options
jstat <-option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

jstat -gc 73608  查看指定进程的堆信息。

3)J D K 工 具 — — j i n f o

用于查看运行中java进程的虚拟机参数。
执行语法:jinfo [option] <pid>

例如:jinfo -flagMaxTenuringThreshold 73608

查看进程73608的虚拟机参数MaxTenuringThreshold的值

3)J D K 工 具 — — j m a p

命令用于生成指定java进程的dump文件; 可以查看堆内对象实例的统计信息, 查看ClassLoader信息和finalizer队列信息。

例如:jmap -dump:format=b,file=/Users/muse/b.hprof 73608

输出进程73608的堆快照, 可使用jhat、visual VM等进行分析

4)J D K 工 具 — — j s t a c k(用的比较多)

命令用于导出指定java进程的堆栈信息。
执行语法:jstack [-l] <pid>

jstack -l 73608 > /Users/muse/d.txt 输出进程73608的实例个数与合计到文件a.txt中
cat /Users/muse/d.txt
DeadLockTest.java

 

jemalloc算法 jvm算法_老年代_29

 5)J D K 工 具 — — j c m d(用的比较少)

命令用于导出指定java进程的堆栈信息, 查看进程, GC等。

执行语法:

jcmd <pid | main class> <command ...|PerfCounter.print|-ffile>

问题:

1、解决问题

如果出现死锁

用jps找到pid

再用jstack 输出堆信息到指定文件

Jstat 查看堆信息的使用情况

2、回收算法和收集器有啥关系

收集器是回收算法的实现

3、full gc 多久一次正常