00:00
好,那么关于我们讲的这个堆空间的一个对象的分配策略啊,实际上我们已经讲完了,那么最后呢,咱们还作为一个补充啊,提到一个新的概念叫做TB啊,很多同学呢,应该是听过这个概念啊,当然也有一些呢,不排除没有听过,那它解决的是什么问题啊,哎,我们来看一下。啊,上来呢,我们就通过一个问题来引入,说为什么要有TLB呢?这是一个缩写啊,叫local location啊a location buffer,就是我们给每个线程单独分配了一个buffer,叫做缓冲区是吧?诶,为什么要有这个结构啊,咱们来看这样一个需求。说呀,咱们讲这个堆,咱们前面已经刚讲这个堆的时候呢,已经明确说过了,它呢是被我们一个进程当中的多个线程所共享的区域。对吧,那它是一个共享区,那就是我们呃,进程当中的任何线程啊,都可以访问到我们堆区当中的共享数据,那当然了有好处,好处呢,就是我们非常方便的,是不是就实现这个进程间的一个通信啊,诶进程间的通信是非常方便的了,哎,这是它的一个好处,那么不好的方面是什么呀?这个我们来看一下,那由于呢,咱们这个对象的实力的创建啊,都是在我们这个堆区中这个实现的,那么GVM的话,就非常频繁的去,呃,在我们这个堆区当中啊,去开辟这个空间去创建对象,那在这个并发的环境下呢,诶,我们这个如果是多个线程都去操作这个一块,这个对空间的这个区域,那有可能会出现这叫线程不安全。
01:24
这个呢应该很好理解对吧,多个线程操作共享数据的话呢,这不是就会出现这个叫线程的不安全机制嘛,而我们这里边儿堆呢,就是共享的这个数据,对吧?诶它呢就会出现不安全,为了避免呢,多个线程操作同一个地址,那我们要想呢,实现它是一个安全的怎么办呀,咱们就要考虑使用这个叫加锁的机制,但你要一加锁咱都知道使用同步的话呢,好处呢是实现显安全了,但是呢,会影响我们程序的执行效率。相当于是一个串行的一个过程,对吧,那这时候呢,我们这个TLB呢就应运而生,那下一个问题就说到底什么是TLB呢?哎,我们来看这个事情,咱这儿呢,是主要是从这个内存的一个分配的角度来说的,而不是从这个垃圾回收的角度来讲啊,那对于内存分配的时候呢,我们在这个伊甸园区啊,给每一个县城再独立的分配一个私有的缓存区域,就是每个县城你自己独有一份的啊,是在我们这个伊甸园区呢进行分配的,这个大家要注意,从这个内存图上来看的话呢,就是这样子的,哎,我给大家呢画了个图。
02:24
这呢是咱们整个这个进程当中这个堆区,堆区中的这个伊甸园区,那这个伊甸园区呢,我们又划分出来了,这样针对你现在有四个一个进程当中有四个线程,我就划分出来了四块,这个TLB啊,每个线程一份,注意我这块画的呢,比例呢,是稍微有点夸张的啊,这个一会儿我们看这个具体的比例大概是占多少啊,那么每个线程呢,有一份啊,这个大家要注意,然后呢,每个线程在使用的时候呢,它呢就是有一个头部是吧,你可以用其中的一部分来分配这个对象空间,如果呢,这个还有还有呢就再分配,那如果说你这个TLB呢,用完了,用完的时候呢,你再使用我们这个公共的这个伊甸园的这个空间。
03:05
哎,是这样的一个情况,那么这样的好处是什么呢?大家应该也非常容易的能够看到啊,就是如果是多个线程来共同操作这个内存的时候呢,由于呢,咱们是不是各自有一份儿啊,那很显然的话呢,就不存在这个线程的安全问题了,或者叫避免了现程安全问题,对吧?好,那么同时的话呢,由于你呃没有这个现成的安全问题,不用考虑同步了,那我们同时呢,能够提升内存分配的一个吞吐量。哎,咱把这种分配方式啊,称为叫快速分配方式啊,直接呢,就放到你各自线程这个独一份的TLB当中啊,目前呢,所知的呃,这个所以所能看到的这个open jdk衍生出来的这个GM,包括呢,像这个阿里的这个淘宝的这个GM等等是吧,所凡是由这个open jdk衍生出来这个GM呢,都提供了支持TLV的这样一个策略。那这个大家注意一下,好,那么下边我们再来看针对TLB的一个进一步的说明。说尽管不是所有的对象势力呢,都能够在这个TRB当中呢,进行成功分配,为啥呀,因为这个空间呢,相对来说还是比较小的,对吧,你看这我写到了,说这个TRB的空间呢,它仅占仅占我们整个伊甸园区的1%,所以这个空间啊,还是非常小的。
04:14
啊,你不可能10%,那万一我们这个进程呢,有十个线程,那每个分一份,这这就废了对吧?诶它的空间呢非常小,但是呢,确实咱们GM呢,把这个TLB呢,是作为我们内存分配的一个首选了。诶这个大家,嗯,这个大家注意一下这个问题,就是我们都作为这个首选,那咱们呢,可以通过在程序当中使用这样的一个参数,嗯,确认呢是否开启了这个TL,咱这呢也可以做一个简单的测试,这呢又是一个非常简单的一个代码,嗯,这呢是打酱油的啊然后呢,下边是有一个这个1000秒的一个sleep。啊,我们现在呢,把这个程序呢,给大家抛起来。那就是不让我们这个进程呢,及时的终止啊,然后呢,跟咱们前面呢,测试过的这个情况一样啊,我打开咱们这个命令行啊CMD,首先呢,我GPS一下查看咱们当前的这个进程,咱们当前写的这个程序的进程呢,是6276啊好接着我们使用呢叫接音,然后杠flag。
05:10
嗯,下边呢,我们写个叫U4,呃,T lab对吧,然后后边再空格一下,写咱们这个进程6276啊一回车,好,那此时的话呢,大家能看到我们这个tleb use前面呢是一个加号,这个加号呢,就意味着我们是开启状态。那咱们当前这个程序你注意啊,我这个test ask这个test这个程序,咱们把它关掉了,来这我们看一下。那这这里边儿我是没有配任何参数的,那也就是说我们这个U4TLB这个参数呢,默认情况下呢,是不是开启呢?哎,我们这写一下啊默认。哎,情况是哎开启的,也就是说呢,既然你开启的话,那我们就相当于是把对象的一个分配呢,呃,使用TLB就作为一个首选,嗯,OK清楚了是吧?然后呢,它仅占我们1%的这个1D的空间,咱们也可以通过这样个参数呢,去设置这个比例啊,凡是呢,就是固定的这个呢,通常咱们都有相应的一些参数呢进行设置,这个呢就不多说了啊,那如果大家想看这个参数具体怎么用的话呢,你也可以去搜索一下,咱们之前呢,带大家也看过的,就是我们Oracle官网关于这个参数的一个设置的这个表,对吧,你在这表里边去找这个参数啊,对它呢进行进一步的理解,好,我这呢就过了行,下个问题就是说一旦呢,这个对象呢,在t l VT lab这个空间呢,分配失败了啊,比如说这个空间不够是吧,失败之后怎么办呀,那此时呢,咱们GM呢,就尝试呢,使用叫加速的机制,确保这个数据的一个操作的原始性。
06:40
啊,这个安全性包括是吧,你想想你多个线程呢,如果都要是来操作这个非TLB这个空间的时候呢,呃,你这个数据呢,写了一半,我这个线程哎也过来了,我也要从这开始写,这呢是造成这个数据的覆盖,诶这就不安全了。哎,这要注意啊,就是说诶我们使用这个加载机制,大家呢,应该也很好理解,下边呢,我们来看一下,整体上关于加上TLB之后呢,一个图示,我们呢,在这个对空间中,我们比如说要nu对象,那nu对象呢,前提呢,我们先要保证当前这个类呢,New的这个对象所属的类是不是要加载过呀,所以针对这个自解码,这个自解码这个数据,我们这个有一个加载的过程是吧?这个loading linking和这个initialization啊,这个类的加载过程咱们前面已经讲过了,那判断一下你当前那一类呢,是不是加载,如果没加载了你就加载,如果加载的话呢,我们直接就进来,进来的时候呢,此时我们要new一个对象嘛,比如说我们要new个person。
07:33
啊,这个我随便举个例子啊,Person呢,就是我们自己定义了一个类的这个对象,那前面呢,我们有一个关键字,这个叫new啊,那此时呢,这个new对应的我们底层呢,是一个也是一个初级服,也是个叫new,它呢就会在我们这个堆空间当中啊,去开辟这个空间了,那开辟空间的话呢,咱们优先考虑呢,就是在这个TB,就是你独立的这个线程,独一份的这个空间当中去放你new的这个对象。
08:00
对吧,诶在这去放,那如果能放的话呢,那最好了,放完以后就是你把对象放在TLB这个空间以后呢,直接呢,我们在构造器当中,你可能是不是要对这个相关的一些属性呢,进一些初始化赋值啊,比如说它涉及到的一些年龄啊,姓名啊,呃这个呃等等这样的一些参数呢,我们进行一个初始化,这就涉及到对象的一个实例化啊,这样的一个问题。OK,那如果说这个空间呢,TLB没有成功,那延爱之呢,就是这个对象呢,可能比较大啊,已经超出了我们这个TLB呢,可能容纳这个空间了,或者说我这已经有一些对象了,再放也放不下了,对吧,那我们就考虑呢,在这个剩下非TLB的那个,呃,公共的这个E点园区呢进行分配,那能能分配的话呢,那就分配好再进行一个初始化就可以了。啊,那如果说这个分配失败呢,这个失败呢,其实就意味着我们一地园区呢,可能空间也不够,我们呢,可能会进行这个GC是吧,那进行这个样JC之后呢,那又可以了,那我们就再给人家分配,那因为对象呢,我们说优先呢,要分配在这个一点元区对吧,当然这里边也不是那么绝对啊,那如果说你这个对象还是个超大的对象,别说这个TLB存不下了,伊甸园都存不下,一甸园区存不下的话呢,通常这个survivor区是不是也都存不下。
09:11
我说的这个存不下,指的是咱们经营完这个GC之后,你还存不下。你像你这个新生,这个伊甸园区都这些过了,通常呢,是不是就都归零了是吧,那这时候你还放不下,那说明这个survivor区呢,一般也放不下了,因为一般都比它小,那就直接O区了,就相当于是个大对象直接进入老年代了,咱们前面已经说过对吧?OK,这呢,就是我们说这个分配的一个过程,行,那如果在面试当中人家提到了说这个呃堆空间一定都是共享的吗?那这时候大家就知道啊,其实呢,我们还有一个被每一个线程所私有的一个空间,叫做t lab啊,为什么要有它啊,它是什么意思,如何进行一个设置啊,整个过程是什么样子的?哎,我们这常说的都比较清楚。
我来说两句