JVM

1、类加载过程

类加载器主要做了什么事情:
image.png

  • 加载阶段: 将我们的class文件(二进制流)从磁盘加载到内存中去,并且在堆内存中创建该类的class对象。

    1.加载阶段采用双亲委派模型,一个类只会被加载一次,现在查询该class文件是否加载过,加载过的就不会再被加载。没有没加载过,从启动类加载器进行加载,加载不了让子类去加载。(不同的类加载器加载的class文件是相互隔离的)

image.png

  • 连接阶段(分为3步):
    1.验证阶段: 验证在连接阶段中的主要目地是确保class文件的字节流所包含的内容符合JVM规范,并且不会出现危害JVM自身安全的代码。但验证不符合要求时,会抛出VerifyError这样的异常后其子异常。

    1. 准备阶段: 为类属性赋初始默认值,***静态变量***分配内存和初始化默认值,final修饰的常量在该阶段已经进行赋值
    2. 解析: 解析就是在常量池中寻找类、接口、字段和方法的符号引用,并且将这些符号引用替换成直接引用的过程。
  • 初始化阶段: 初始化阶段是类的加载过程的最后一个阶段,为所有的类属性赋予正确的值。

2、垃圾回收算法

JVM支持垃圾自动回收,我们应用程序执行起来的时候,默认就会存在我们的GC线程

查找垃圾

1.引用计数法(无法解决对象相互引用的问题)
2.根可达算法

1、垃圾回收算法

回收垃圾算法

1.复制算法(内存利用率不高)

将现有的内存空间分为两半A和B,所有的新对象的内存都在A中分配,然后当A用完了之后,就开始对象存活判断,将A中还存活的对象复制到B去,然后一次性将A中的内存空间回收掉。

在分代模型中,Eden区要比Survivor区大这么多(默认8:1),要是一次GC之后的存活对象的大小大于Survivor区,发生内存分配担保
当发生了上面这种情况,新生代需要老年代的内存空间来做担保,把Survivor存放不下的对象直接存进老年代中。

2.标记清除(产生内存碎片)

首先标记出所有需要回收的对象,然后统一对标记的对象进行回收,当一个大对象在申请空间时无法找到一个连续的大内存就会出发GC

3.标记整理

标记-整理其GC的过程与标记-清除是一样的,只不过会让所有的存活对象往同一边移动,这样一来就不会像标记-清除那样留下大量的内存碎片。

2、常见垃圾回收器

常见的垃圾回收器

image.png

Serial,Serial Old是最先发布的垃圾回收器单线程运行,垃圾回收在工作的时候会停止所有工作线程,这个时间成为STW(stop the world)。用户体验很差劲。随后推出了ParNew,ParNewOld两个并行执行的垃圾回收器,发布多CPU的优势。但是在工作时依然会存在STW

1、CMS垃圾回收器

CMS是一款并发老年代垃圾收回器(和工作线程可以同时进行)

和工作线程并发执行会面临问题,采用三色标记算法进行垃圾回收

三色标记:

  • 黑色:该对象已经被标记过了,且该对象下的属性也全部都被标记过了。(程序所需要的对象)
  • 灰色:该对象已经被标记过了,但该对象下的属性没有全被标记完。(GC需要从此对象中去寻找垃圾)
  • 白色:该对象没有被标记过。(对象垃圾)

存在问题:

1、浮动垃圾:并发标记的过程中,若一个已经被标记成黑色或者灰色的对象,突然变成了垃圾,此时,此对象不是白色的不会被清除,重新标记也不能从GC Root中去找到,所以成为了浮动垃圾,这种情况对系统的影响不大,留给下一次GC进行处理即可。

2、漏标:一个未被标记的白色对象被一个黑色对象重新引用,该对象最终会被当作垃圾被清除,解决方法(写屏障),当一个白色对象被黑色对象引用,将黑色对象标记为灰色。其中还存在一个致命的问题:一个灰色的对象当一个属性被标记后指向了一个白色的对象,当前对象为灰色,不会在重新查找太已经找过的属性,最终无法标记。解决方法: gc扫描结束后,出发STW再次进行一个GC,应为之前已经找到了引用树,这次遍历会快的多。

总结: CMS依然存在STW只是时间上会短很多,效率高很多

线上参数

按需配置

-server -Xms4g -Xmx4g -Xmn2g 
-XX:MetaspaceSize=256m 
-XX:MaxMetaspaceSize=512m 
-XX:MaxDirectMemorySize=1g 
-XX:SurvivorRatio=10 
-XX:+UseConcMarkSweepGC 
-XX:CMSMaxAbortablePrecleanTime=5000 
-XX:+CMSClassUnloadingEnabled 
-XX:CMSInitiatingOccupancyFraction=80 
-XX:+UseCMSInitiatingOccupancyOnly 
-XX:+ExplicitGCInvokesConcurrent 
-Dsun.rmi.dgc.server.gcInterval=2592000000 
-Dsun.rmi.dgc.client.gcInterval=2592000000 
-XX:ParallelGCThreads=4 
-Xloggc:/home/admin/logs/gc.log 
-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/home/admin/logs/java.hprof 
-Djava.awt.headless=true 
-Dsun.net.client.defaultConnectTimeout=10000 
-Dsun.net.client.defaultReadTimeout=30000 


# 基础 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×