JAVA基础笔记4(JVM标记清除算法和JMM内存模型)

JAVA基础笔记4

JVM GC垃圾回收

标记清除算法
在这里插入图片描述
标记压缩算法

在这里插入图片描述

标记清除压缩算法

在这里插入图片描述

JVM 总结

  • 内存效率算法顺序:复制算法 > 标记清除算法 > 标记压缩算法(时间复杂度)
  • 内存整齐度算法顺序:复制算法 = 标记压缩算法 > 标记清除算法
  • 内存利用率算法顺序:标记压缩算法 = 标记清除算法 > 复制算法

没有最好的算法,只有最合适的算法:GC:分代收集算法

  • 年轻代:存活率低,复制算法
  • 老年代:区域大:存活率高,标记清除算法(内存碎片不是太多的情况下可以多清除几次)+ 标记压缩(然后再来把内存碎片压缩)混合实现。

JMM

1,什么是JMM?

JMM:(Java Memory Model的缩写),Java内存模型,一种抽象的概念
Java内存模型定义了共享内存系统中多线程程序读写操作行为的规范,Java内存模型也就是为了解决这个并发编程问题而存在的。(解决原子性,可见性,有序性的问题)。
说白了就是:多条线程去进程的共享主内存里面拷贝同一个变量数据,在线程的工作内存中修改数据,保证能同步到主内存中去,保证其他的线程能拿到一样的数据,而定义的一种规则和协议。

2,它是干嘛的?

作用:缓存一致性协议,用于定义数据读写的规则(遵守,找到这个规则)。
JMM定义了线程工作内存和主内存之间的抽象关系:线程之间共享的变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory)

JMM原理流程图
在这里插入图片描述

  • 原子性:指的是一个操作中有多条指令在执行,不可以有单独或个别指令报错或中途暂停然后再调度,要么全部不执行,要么就全部执行完成。

扩展:我们都知道CPU有时间片的概念,会根据不同的调度进行线程调度,而当线程在执行一个读写改操作是,在执行完读改之后,时间片耗完,就会被要求放弃CPU,并等待重新调度。这种情况下读写改就不是一个原子操作,即存在原子性问题。

  • 可见性:值的是多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看到修改后的值。

扩展:多个线程访问进程中的某个共享内存时,这多线程是分别在不同的CPU上执行的,则每个CPU都会在各自的cache中保留一份共享内存的缓冲,由于多核是可以并行的,可能会出现多个线程同时写各自缓存的情况,而各自的cache之间的数据就可能不同,这就存在可见性问题。

  • 有序性:指的是程序执行的顺序按照代码的先后顺序执行,而不能乱重排,导致程序出现不一致的结果。

扩展:由于处理器优化和指令重排以及CPU还可能对输入代码进行乱序执行,比如load – add,有可能被优化成 add – load,这就是有序性问题。

其实就是为了实现多个线程的工作内存的数据一致性,让程序在多线程并发,指令重排序优化的环境中也能如预期中一样执行。

  • 解决共享对象可见性这个问题:volatile关键字,synchronized和lock也能够保证可见性,lock和synchronize能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将变量的修改刷新到主内存当中,因此可以保证可见性。
  • 解决并发编程中的原子性问题:使用synchronized关键字和lock,能够保证任一时刻只有一个线程执行该代码块,从而保证了原子性。
  • 解决有序性问题:其实也就是我们所说的重排序问题,volatile关键字也会禁止指令的重排序,而synchronized关键字由于保证了同一时刻只允许一条线程操作,自然也就保证了有序性。

JMM定义了哪些操作来完成主内存和工作内存的交互操作,如下图。

在这里插入图片描述
volatile如何生效的:

当一个共享变量被volatile修饰时,它会保证修改的值被立即更新到主内存中,当有其他线程读取该值时,也不会直接读取工作内存中的值,而是直接去主内存中读取。

JMM的八种交互操作

  1. lock(锁定):作用于主内存的变量,把一个变量标识为线程独占状态。
  2. unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
  3. read(读取):作用于内存变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load使用。
  4. load(载入):作用于工作内存的变量,它把read操作从主内存中变量放入到了工作内存中。
  5. use(使用):作用于工作内存中的变量,它把工作内存中的变量传输给执行引擎,每当虚拟机遇到一个需要使用到变量的值,就会用到这个指令。
  6. assign(赋值):作用于工作内存中的变量。它把一个从执行引擎中接收到的值放入工作内存的变量副本中。
  7. store(存储):作用于工作内存中的变量,它把一个从工作内存中一个变量的值传送到主内存中,以便后续的write使用。
  8. write(写入):作用于主内存中的变量,它把store操作从工作内存中得到的变量放入主内存的变量中。

对八种操作的规则:

  1. 不允许read和load,store和write操作之一单独出现。即使用了read必须load,使用store必须write。
  2. 不允许线程丢弃他最近的assign操作,即工作变量的数据改变之后,必须告知主内存空间。
  3. 不允许一个线程将没有assign的数据从工作内存同步回主内存。
  4. 一个新的变量必须在主内存中诞生,不允许工作内存使用一个未被初始化的变量,就是对变量实施use,store操作之前,必须经过assign和load操作。
  5. 一个变量同一时间只有一个线程能对其进行lock,多次lock之后,必须执行相同次数的unlock才能解锁。
  6. 如果一个变量进行lock操作,会清空所有工作内存中此变量的值,在执行引擎使用这个变量前,必须重新load或assign操作初始化变量的值。
  7. 如果一个变量没有被lock,就不能对其进行unlock操作。也不能unlock一个被其他线程锁住的变量。
  8. 对一个变量进行unlock操作之前,必须把此变量同步回主内存里。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值