Java JVM总结

一、jvm参数

1)内存

-Xms

-Xmx

-Xss

-Xloggc:file

-Xprof

-XX:+DisabledExplicitGC

-XX:PreBlockSpin

-XX:CompileThreshold

2)Parallel

-XX:SurvivorRatio
-XX:PreTenureSizeThreshold
-XX:MaxTenuringThreshold
-XX:+ParallelGCThreads
-XX:+UseAdaptiveSizePolicy

3)CMS

-XX:+UseConcMarkSweepGC

-XX:MaxTenuringThreshold

-XX:ParallelCMSThreads

-XX:CMSInitiatingOccupancyFraction

-XX:+UseCMSCompactAtFullCollection

-XX:CMSFullGCsBeforeCompaction

-XX:+CMSClassUnloadingEnabled

-XX:CMSInitiatingPermOccupancyFraction

-XX:GCTimeRatio

-XX:MaxGCPauseMillis

4)G1

-XX:+UseG1GC

-XX:MaxGCPauseMillis

-XX:GCPauseIntervalMillis

-XX:+G1HeapRegionSize

-XX:G1NewSizePercent

-XX:G1MaxNewSizePercent

-XX:GCTimeRatio

-XX:ConcGCThreads

-XX:InitiatingHeapOccupancyPercent

二、内存模型

(1)运行时数据区

程序计数器

Java 虚拟机栈

本地方法栈

Java 堆

方法区

(2)对象内存分配

1)内存分配方式

指针碰撞、空闲列表

2)内存分配策略

优先在 Eden 区分配、大对象直接进入老年代、长期存活对象将进入老年代

3)内存分配空间

1.栈分配

技术:逃逸分析、标量替换

缺点:无法栈上分配共享的对象 

2.TLAB

优点:尽量避免从堆上直接分配内存从而避免频繁的锁争用

缺点:有内存孔隙问题,影响 gc 扫描性能 

3.Eden

4.年老代

4)内存分配并发安全问题

同步处理(采用 CAS + 失败重试)

TLAB 上分配

5)对象的创建方式

new、Class.newInstance、Constructor.newInstance、clone、反序列化

6)对象的访问定位

句柄 、直接指针(HotSpot)

7)引用类型

强引用、软引用、弱引用、虚引用(幽灵引用/幻影引用)PhantomReference 

8)对象拷贝克隆

深拷贝和浅拷贝

拷贝有两种方式:
实现 Cloneable 接口并重写 Object 类中的 clone()方法;
实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真
正的深度克隆

9)内存使用

1.内存溢出

OOM错误:stackoverflow错误,permgen space错误

2.内存泄漏

类的静态变量

各种连接,如数据库连接、网络连接和IO连接等

变量不合理的作用域

内部类持有外部类

改变哈希值

单例模式

监听器

ThreadLocal的误用

三、GC

(1)判断垃圾

1)算法

引用计数(缺点:不能解决循环引用)、根可达性分析

2)GC roots

1.虚拟机栈(JVM stack)中引用的对象

2.方法区中类静态属性引用的对象

3.本地方法栈(Native Stack)引用的对象

(2)垃圾回收算法

复制、标记清除、标记整理、分代回收、分块回收

(3)hopspot垃圾回收器

1)GC类型

Minor GC

Major GC

Full GC(Major GC对老年代/永久代的stop the world的GC)

Mixed GC(G1)

1)新生代回收器

serial、parNew、parallelScavenge

2)老年代回收器

CMS、serialOld、parallelOld 

3)整堆回收器

G1

关系:(serial和parNew)搭配(CMS和serialOld)、parallelScavenge搭配(serialOld和parallelOld)、CMS并发模式失败后以serialOld做备份

4)CMS

1、运作步骤

初始标记(stop the world)、并发标记、重新标记(stop the world)、并发清除

2、优点

并发收集、低停顿

3、缺点

CMS收集器对CPU资源非常敏感

CMS收集器无法处理浮动垃圾(Concurrent Mode Failure)

CMS收集器会产生大量空间碎片

5)G1

1、特点

并行于并发、空间整合、可预测的停顿、分代收集

2、运作步骤

初始标记、并发标记、最终标记、筛选回收

(4)垃圾回收机制

1)GC触发的条件

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

Full GC触发条件:

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

2、老年代空间不足

3、方法去空间不足

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

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

6、 CMS GC时出现promotion failed和concurrent mode failure 

2)年轻代到年老代的晋升过程的判断条件

1、长期存活的对象进入老年代(15次MinorGC,JVM参数-XX:MaxTenuringThreshold)

2、动态对象年龄判定(大于等于某个年龄的对象超过了survivor空间一半)

3、如果对象的大小大于Eden的二分之一会直接分配在old,如果old也分配不下,会做一次majorGC。如果小于eden的一半但是没有足够的空间,就进行minor gc也就是新生代GC,minor gc后,survivor仍然放不下,则放到老年代

3)一次完整的 GC 流程

1.大对象直接进入到老年代
2.小对象先在eden区分配内存,当eden满了后,触发一次Minor GC,清理eden区域
3.存活下来的对象进入到survivor区域,年龄+1
4.当年龄>15(默认)时进入到老年代,当老年代满了后触发一次Full GC

4)fullGC 很频繁,线上排查问题

查看gc.log

 jmap -histo:live pid

-XX:+HeapDumpBeforeFullGC

jstat -gcutil pid

四、jvm分析

(1)jvm命令工具

jstack
jmap
jhat
jstat
jinfo
jps
jconsole, jvisualvm

(2)线程堆栈

1)线程堆栈信息

线程的名字、线程的优先级、线程 id、线程的状态、线程占用的内存地址、线程的调用栈

2)线程状态

NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED

3)分析性能问题

1、系统无缘无故的cpu过高

2、系统挂起,无响应

3、系统运行越来越慢

4、性能瓶颈(如无法充分利用cpu等)

5、线程死锁,死循环等

6、由于线程数量太多导致的内存溢出(如无法创建线程等)

五、类加载

(1)双亲委派模型

类加载器:Bootstrap、Extension、Application

(2)打破双亲加载

JNDI、JDBC、Tomcat

(3)类加载过程

装载、链接(验证、准备、解析)、初始化、使用、卸载

(4)类的实例化顺序

父类静态变量->父类静态代码块->子类静态变量->子类的静态代码块->父类成员变量->父类代码块->父类构造方法->子类成员变量->子类代码块->子类构造方法

(5)类装载方式

1)隐式装载

创建类对象、使用类的静态域、创建子类对象、使用子类的静态域。

其他特殊的隐式加载:
在JVM启动时,BootStrapLoader会加载一些JVM自身运行所需的class
在JVM启动时,ExtClassLoader会加载指定目录下一些特殊的class
在JVM启动时,AppClassLoader会加载classpath路径下的class,以及main函数所在的类的class文件

2)显式装载

ClassLoader.loadClass(className) :只执行装载过程。

Class.forName(className):执行类的装载、链接、初始化过程

注:1、Class.forName(className)是初始化类,newInstance()是实例化类。new是初始化加实例化类。2、new关键字和Class类的newInstance()的区别

posted @ 2021-06-21 22:12  茅坤宝骏氹  阅读(5)  评论(0)    收藏  举报  来源