JVM垃圾回收理解,垃圾回收算法、JVM堆内存分代模型

我们写java代码的时候,业务逻辑处理里面会产生很多对象,这些对象在调用结束后jvm的垃圾回收器GC就帮我们回收处理了,但是具体的逻辑是如何处理的,如何如优化。

1、什么是垃圾?

简单来说就是:
没有任何引用指向这个对象,那这个对象对jvm来说就是垃圾,需要回收。

2、jvm如何定位到这些垃圾?使用的什么算法

jvm定位垃圾的算法有两种:

1:引用计数器

顾名思义,就是通过计数来判断这个对象是否被引用。
当一个对象有引用时计数器+1,引用消失时计数器-1,当计数器为0的时候,对象不在被引用,也就标记为垃圾。这种算法比较简单,通过计数器操作,但是有一个致命的问题就是循环引用,对象A引用了对象B,B也引用了A,但是A和B没有被第三个对象应用。

2:根可达算法

这个也很好理解,就是从根开始往下面捋,通过根能引用到的就是有用的,剩下引用不到的就是垃圾。也就是先找到有用的对象,剩下的就是没用的。通常用GC Roots作为起点。

3、常见的垃圾回收算法
1:标记清除

这里分为两个阶段:标记和清除,在jvm定位垃圾的时候对对象进行标记,标记完成后统一回收这些被标记为垃圾的对象。
缺点:
1、效率不高
2、标记位置不连续,容易产生内存碎片
在这里插入图片描述

2:拷贝算法

拷贝算法是将内存分为相同的两块区域,每次使用其中一块,当这块内存使用完了,就将其中还存活的对象负责到另外一块内存空间,当前的这块清空,没有碎片产生。
缺点:每次是使用了一半的内存,内存空间没有有效利用,浪费了空间
在这里插入图片描述

3:标记压缩

这个和标记清除比较类似,标记的过程和标记清除一样,但是标记完成后,不是对垃圾进行回收,而是把正常存活的对象压缩到内存的一段,然后将这个边界外的全部清除。
在这里插入图片描述

4、JVM堆内存分代模型

1、java堆是所有线程共享的,是java虚拟机管理的内存中最大的一块,堆内存在虚拟机启动时创建。
将堆内存分为几块,分别对应新生代、老年代、永久代;
2、新生代:刚new出来的对象放入新生代,垃圾回收一次后还存活的会放入幸存区survive;(新生代包括Eden区、From Survivor区、To Survivor区,系统默认大小Eden:Survivor=8:1)。

3、老年代:新new的很大的对象和survive幸存区回收好多次没有回收掉的,进入老年代,老年代存放的是生命周期比较长的对象,老年代进行FULL GC。
对象超过多大直接进入老年代可以通过参数设置:
-XX:PretenureSizeThreshold
幸存区经历多少次GC后进入老年代也可以设置:
XX:MaxTenuringThreshold
4、永久代/元空间:存放class对象(jdk1.8之后叫Metaspace元空间,元空间的本质和永久代类似,都是对JVM规范中方法区的实现。)
区别:
1、元空间并不在虚拟机中,而是使用本地内存;
2、永久代必须设置内存大小,元空间可以设置也可以不设置,受限物理内存

堆内存逻辑分区:
在这里插入图片描述
STW:Stop the Word,当JVM进行FULL GC的时候会产生。

5、JVM虚拟机栈

1、java虚拟机栈是线程私有的,生命周期和线程相同;
2、每个方法被调用到完成的过程,都对应一个栈帧在虚拟机栈中的入栈和出栈的过程;
3、虚拟机栈是执行java方法的内存模型服务,在每一个方法执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息;

6、方法区

可通过参数-XX:MaxPermSize设置
1、方法区是所有线程共享的内存区域,用于存储已被虚拟机加载的类信息,常量,静态变量;
2、方法区存放java类定义的信息,和垃圾回收关系不大,可以设置不实现垃圾回收,但是不是说没有垃圾回收;
3、方法区域的内存主要回收目标是针对常量池的回收和类型的卸载;
4、运行时常量池也是方法区的一部分,虚拟机加载Class后把常量池的数据放入运行时常量池;

7、常用JVM参数设置
参数说明实例
-Xms初始堆大小,默认物理内存的1/64-Xms512M
-Xmx最大堆大小,默认物理内存的1/4-Xmx2G
-Xmn新生代内存大小,官方推荐堆内存的3/8-Xmn512M
-Xss线程堆栈大小,jdk1.5之后默认1M-Xss512K
-XX:NewRatio=n设置新生代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4-XX:NewRatio=3
-XX:SurvivorRatio=n年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:8,表示Eden:Survivor=8:1:1,一个Survivor区占整个年轻代的1/8-XX:SurvivorRatio=8
-XX:PermSize=n永久代初始值,默认为物理内存的1/64-XX:PermSize=128M
-XX:MaxPermSize=n永久代最大值,默认为物理内存的1/4-XX:MaxPermSize=256M
-verbose:class在控制台打印类加载信息
-verbose:gc在控制台打印垃圾回收日志
-XX:+PrintGC打印GC日志,内容简单
-XX:+PrintGCDetails打印GC日志,内容详细
-XX:+PrintGCDateStamps在GC日志中添加时间戳
-Xloggc:filename指定gc日志路径-Xloggc:/data/jvm/gc.log
-XX:+UseSerialGC年轻代设置串行收集器Serial
-XX:+UseParallelGC年轻代设置并行收集器Parallel Scavenge
-XX:ParallelGCThreads=n设置Parallel Scavenge收集时使用的CPU数。并行收集线程数-XX:ParallelGCThreads=4
-XX:MaxGCPauseMillis=n设置Parallel Scavenge回收的最大时间(毫秒)-XX:MaxGCPauseMillis=100
-XX:GCTimeRatio=n设置Parallel Scavenge垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)-XX:GCTimeRatio=19
-XX:+UseParallelOldGC设置老年代为并行收集器ParallelOld收集器
-XX:+UseConcMarkSweepGC设置老年代并发收集器CMS
-XX:+CMSIncrementalMode设置CMS收集器为增量模式,适用于单CPU情况
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值