JVM内存模型与垃圾回收

参考书籍

深入理解Java虚拟机:JVM高级特性与最佳实践(最新第二版)
Java虚拟机-JVM故障诊断与性能优化(第二版)

JVM和Java HotSpot

java -version出来信息包含两部分:Java软件包发行版本信息和内核(JVM)版本信息。
在这里插入图片描述
图中虚拟机(JVM)版本是25.121-b13

1 JVM内存结构及说明:

1.1 结构

在这里插入图片描述
在这里插入图片描述

1.2各部说明

1.2.1 程序计数器

它是当前线程执行字节码的行号指示器,字节码解释器通过改变行号指示器来选取下一条指令执行,一个线程对应一个计数器。

1.2.2 虚拟机栈和本地方法栈

虚拟机栈由栈桢为单位组成,栈帧由三部分组成:局部变量区、操作数栈、帧数据区。
虚拟机栈没有单独内存分配参数,但可以通过设置线程的栈大小-Xss,虚拟机栈和线程生命周期相同。
线程执行方法入口和出口时,JVM会给线程对应的当前栈压入栈桢和弹出栈桢。局部变量表存放了编译期可知的各种基本数据类型。

1.2.3 堆

堆是存放对象实例和数组的区域,是垃圾回收的重点区域。

1.2.4 方法区(JDK8开始,永久代(PermGen)的概念被废弃掉了,取而代之的是一个称为Metaspace的存储空间。)

在这里插入图片描述

1.2.5 直接内存(Direct Memory)也叫堆外内存(不在运行时数据区)

java.nio.DirectByteBuffer对象进行堆外内存的管理和使用,它会在对象创建的时候就分配堆外内存。
在这里插入图片描述
直接内存满的时候不能进行GC回收,只能等到老年代满Full GC时,才对它进行GC回收。

1.2 JVM参数说明

-Xmx JAVA堆的最大值,默认为物理内存的1/4
-Xms JAVA堆内存的初始,一般最好和-Xmx一样大,避免在程序运行过程中动态的申请调整堆内存
-Xmn:年轻代大小(Eden+2Survivor)
-Xss 每个线程的stack大小
方法区
jdk1.8之前设置
-XX:PermSize:设置持久代内存大小(永久代也称方法区,jdk8 取而代之的元空间(Metaspace))
XX:MaxPermSize:设置最大值持久代内存大小,永久代不属于堆内存,堆内存只包含新生代和老年代。
jdk1.8之后设置(Metaspace使用的是本地内存,而不是堆内存,也就是说在默认情况下Metaspace的大小只与本地内存大小有关。)
-XX:MetaspaceSize=N
-XX:MaxMetaspaceSize=N
NewRatio: 老年代对比新生代的空间大小, 比如2代表老年代空间是新生代的两倍大小
SurvivorRatio: Eden/Survivor的值. 这个值的说明, 8表示Survivor:Eden=1:8, 因为survivor区有2个, 所以Eden的占比为8/10

2 GC:

2.0 垃圾对象

a.判断对象存活算法 
2.1.0 引用计数法(不适应)
   对象配备一个整形计算器,被引用一次+1,引用失效时-1,当值为0时,对象将被回收。
  缺陷:
       无法处理循环引用。两个对象相互引用,则不会被回收,因此在java收集器中没有这种算法。
       引用计算器对性能有一定影响。 
2.1.0 可达性分析算法
	通过根节点(GC Roots)标记所有从根节点开始的可达对象,未被标记的对象就是未被引用的垃圾对象
b.判断可触及性来确定垃圾对象
	可触及性包括3个状态。
		1.可触及的
		2.可复活的
		3.不可触及的 

2.0 垃圾回收算法

2.1 标记清除法(Mark-Sweep)
它将垃圾回收分为两个阶段:
	标记阶段:通过根节点标记所有从根节点开始的可达对象,未被标记的对象就是未被引用的垃圾对象,
		未被标记的对象就是未被引用的垃圾对象。
	清除阶段:清除未被标记的对象,缺点是可能产生空间碎片。
一般用在老年代GC
2.2 复制算法(Copying)

将内存空间分为两块,每次只使用一块,在进行回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,
之后清除下在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。
一般用在新生代GC
优点:确保内存空间没有碎片。
缺点:性能损耗大
在JAVA的新生代串行垃圾收集器中使用了复制算法的思想。

2.3 标记压缩法(Mark-Compact)

它不需要将内存分为两块,标记后将存活对象移动到内存一端,清理边界外的一端,避免了内存碎片的产生。
效果等同于标记清除法+碎片整理。
一般用在老年代GC

2.4 分区算法(Region)

分区算法将堆空间划分成连接的不同小区间,每个区间独立使用,回收。每次回收若干个区间,不用回收整个堆。

2.2 垃圾收集器

2.2.1 serial/serial Old 收集器
2.2.1.1 概念

serial收集器是单线程收集器,发生GC时会停止所有工作线程,常用Client 模式下的虚拟机。

2.2.1.2 serial 收集器

serial收集器是针对年轻代大小(Eden+2Survivor),
采用复制算法,GC时会停止工作线程,将Eden中存活下来的对象复制到 To Survivor 和Old中,然后清空Eden 和 from Survivor。

2.2.1.3 serial Old 收集器

serial收集器是针对老年代大小(Old),GC时会停止工作线程,采用标记-整理算法,
将能收集的对象进行标记再清除,清除后,对内存空间进行整理。

2.2.2 ParNew/ParNew Old 收集器
2.2.2.1 概念

ParNew收集器是基于serial的多线程收集器(其它和serial收集器一样),常用Server 模式下的虚拟机。

2.2.2.2 ParNew 收集器

ParNew可以和CMS收集器(针对老年代的收集器,它是并发收集器)一起使用,ParNew属于并行收集器。

2.2.2.3 指定该收集器为JVM收集器。

-XX:+UseConcMarkSweepGC :指定ParNew为新生代收集器,CMS为Old收集器。
-XX:+UseParNewGC:强制指定它为收集器。

2.2.3 Parallel Scavenge/Parallel Old 收集器
2.2.3.1 概念

Parallel Scavenge并行多线程收集器,和ParNew相比它是以吞吐量优先为目标的收集器,它拥有自适用调节策略。

2.2.3.2 ParNew 收集器

ParNew可以和CMS收集器(针对老年代的收集器,它是并发收集器)一起使用,ParNew属于并行收集器。

2.2.4 CMS 收集器
2.2.4.1 概念
 CMS是并发多线程收集器,(产生于JDK1.5)与CMS相比有以下优势。
      1.并行与并发。
      2.分代收集。
	  3.可预测的停顿。
2.2.4.2 CMS 收集过程

在这里插入图片描述
初始和重新标记时间短,并发标记和并发清除时间长。

2.2.4.3 CMS 缺陷
	    1.对CPU资源敏感,CPU核数小时,对CPU性能很大影响。
        2. 无法处理浮动垃圾。
        3.它是基于标记-清除算法的收集器,会产生大量内存碎片,给大对象存储带来麻烦。
2.2.5 G1 收集器
2.2.5.1 概念

G1是并发多线程收集器,是一款并发收集,低停顿的收集器(产生于JDK1.7),使用到分区算法。

2.2.5.2 G1 收集过程
概念:G1会把堆分成若干相同大小的Region,各个Region可以相互引用对象,各个引用关系建立在被引用对象所处理Region中的Remembered Set中(其它收集器也使用到Remembered Set)。
	收集过程  
		1.新生代GC
		2.并发标记周期
			2.1初始标记(伴随一次新生代GC)
			2.2根区域扫描
			2.3并发标记
			2.4 重新标记(会停顿)
			2.5独占清理(会停顿)
			2.6并发清理
		3.混合回收
		4.如果有需要,可能会进行Full GC。
2.2.5.3 指定该收集器为JVM收集器。

-XX:+UseG1GC

2.2.5.4 G1对比CMS优势
	    1.并发与并行。
        2.分代收集。
        3.空间整合。
        4.可预测的停顿。

3 多线程执行方法,局部变量

引用博客 https://blog.csdn.net/Hello_Ken/article/details/20177341

对于那些会以多线程运行的单例类(springMvc,springBoot),例如Web应用中的Servlet,Service
每个方法中对局部变量的操作都是在线程自己独立的内存区域内完成的,
所以是线程安全的。
对于成员变量的操作,可以使用ThreadLocal来保证线程安全。
局部变量不会受多线程影响
成员变量会受到多线程影响
多个线程应该是调用的同一个对象的同一个方法:
如果方法里无成员变量,那么不受任何影响
如果方法里有成员变量,只有读操作,不受影响
存在写操作,考虑多线程影响值。
在Java程序中,每当启用一个线程时,JVM就为他分配一个Java栈,栈是以帧为单位保存当前线程的运行状态。
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值