00:00
那接着啊,咱们再来看说呢,这个通常情况下呢,我们访问直接内存的速度啊,它是要优于啊直接呢,访问我们说Java堆的一个速度。啊说它的这个读写性能呢会更高,那怎么去理解这个问题呢?大家呢,可以看我下边放的两个图啊,看我们这两个图,那这儿呢,是我们比较传统的方式啊说使用我们Java的应用程序呢,咱们来访问具体的呃物理内存上的这个文件,那我们这里面需要呢,应用程序,比如我们较读这个物理磁盘中的这个文件的话呢,呃,需要呢,从这个用户带呢,切换为这个叫内核态,也就是说呢,我们这个数据呢,从这个咱们应用程序的这个虚拟机的内存当中去读这个具体的地址上的数据,而这个地址的数据呢,我们还需要呢,去再从内核地址当中呢去获取,然后呢才能对应到咱们物理磁盘上,那写的话呢,也同样的道理,先把这个数据呢,写出到咱们的用户态的这个虚拟的这个内存地址上啊,内存空间上,然后呢,这个数据呢,再被复制到咱们,呃,内核态的就是本地的这个内存空间上,然后呢,再相当于是写入到我们具体的物理磁盘上,所以整个这块儿呢,大家会发现呢,我们经过了两次这个算是整个这个内存空间地址。
01:10
是吧,它的一个复制操作呢,显然使得我们这个效率呢就比较低啊,这是我们说传统的一种状态啊,然后呢,如果我们使用这个叫直接缓冲区的话呢,我们就不会再有这个用户带和内核态这样的两种状态中间的这个copy的过程了,直接呢,我们就存在一个呃,物理映射文件啊,我们应用程序呢,直接呢,就把这个数据,不管你是读也好写也好,直接呢是来映射我们物理存在的这个映射文件啊,这个映射文件。然后呢,我们这个物理磁盘的话呢,也直接呢,是针对于咱们这个物理的内存啊,进行一个映射操作,那相当于省去了中间商是吧?啊这个是避免中间商呢赚差赚差价啊这个呢,我们可以这个交流呢更通畅一些,那显然呢,这个读写速度啊,是不是也要更快一些。那这大家注意是吧,那尤其呢,是对于我们这个读写比较频繁的场合,那你频繁的需要做交互,以及呢,说我们这个数据量比较大的时候呢,这是我们用这个直接内存,它这个效果呢,诶就会更明显一些,诶是这样子的啊那这块儿呢,咱们也给大家呢演示一个例子啊,这以前呢,是在讲这个NIO的时候呢,给大家举的这个讲课的时候呢,一个例子啊,那个这个代码的话呢,我们具体的细节咱们稍微呢,大家看一眼啊是这样子的,我这儿呢,是有一个字符串所代表的一个本地文件啊,用的是个电影啊,一个多G的啊这样的大小,呃,为了呢,能够展示出我们用两种不同的方式呢,谁快谁慢呢,这块我们让它呢复制三次。
02:35
复式三四呢,我们求一个这个总总共花费的这个时间,那一方面呢,我们使用的是比较传统的IO,另外一个呢,是使用我们这个本地内存啊,是这样的两种场景啊,那比如咱们先把这个本地的这个关掉,先使用我们传统这个IO的这样情况啊,这是以前测试的一个时间啊,先可以去掉,那使用传统这个方式呢,我们给它复制三次,那每一次呢,这个名字呢都不一样,所以这儿呢,我们是用了一个for循环,每次的名字不太一样,然后下边呢,就是我们对应这个IO的这个操作使用的叫流。
03:06
那这时候呢,我们这个字节数的大小呢,我用的是100兆啊,那100兆的大小应该说呢不小了。OK是吧,那下边呢,我们就进行这个IO的一个复制操作,那使用这个文件呢,是我在F盘下的一个文件,首先呢,我们来看一下这个文件。L盘,嗯,这个是吧,诶打开以后OK,这呢就是一个电影。啊,这个前段时间说比较火的一个电影啊,然后这个文件的话呢,现在是1.5个GB啊,就是诶这么大行,那现在呢,我把这个电影呢,让它复制三次啊,使用了我们传统的一个IO的方式来使用它,然后这样OK跑一下。这呢,咱们就需要稍微的等一点这个时间啊,嗯,等这个时间呢,你最好不要进行其他一些占用内存比较大的一些操作啊,这时候呢,你有可能会影响到我们这个CPU的一个分配是吧?啊,那最后呢,导致我们这个数据呢,就不会特别精准了啊,你就最好别进行其他过多的操作啊,稍微浏览一下这个页面呢是可以的。
04:07
那比如说我们一会儿要测的就是这个叫direct buffer。那使用的是咱们这个本地的一个字节,这个这个缓冲区是吧,哎,这呢,又出现了咱们这会儿调用的这个aoccate direct。哎,里边呢,用的就是这个本地的直接的一个缓冲区是吧。OK啊。行,那么具体这个代码细节的话呢,咱们就不用多讲了,呃,这个呢,是涉及到大家如果想学习这个NIO的话呢,你就直接呢,在比如哔哩哔哩上或商务官网上呢,你去搜索这个NIO的这个视频学习就行啊,那对应的这个nity的话呢,这个韩老师呢,韩春平老师也录了一套这个视频,大家呢,也可以去看一看啊OK,这呢是我们复制三个啊,这个电影所花费的这个总时间啊,50多秒啊,54秒钟的这个时间来稍微看一眼啊,这呢是复制好的这三个文件,咱们随意的给它打开,看一下它这个大小。
05:04
诶,这个呢,是咱们复制完以后的这个大小啊,这呢是咱们原文件的这个大小没问题,行,其他这个我就不一一的去看了。打开能看吗?这显然是没问题的是吧?在16岁以上才能看啊。嗯,拿到里边有一些。啊,可能有些暴力的是吧,啊色情的也没有啊好,这呢是我们说的这样的一个情况叫IO,然后呢,咱们换成这个叫NIO,我这呢文件名也改一下,改成一个下划线的,把它呢稍微的注释,然后把这个呢我们给它打开。可以了是吧,来我们再进行一个演示啊。嗯。那大家呢,在进行测试的时候呢,你也可以去实验一下,就是我们这儿呢,使用的这个缓冲区,或者我们叫字节数组是吧,这个大小要是不一样的情况下呢,你看看诶这个会影响多少。这个会导致我们这个时间呢,是变化的幅度大不大,哎,当然呢,下来也可以做一个演示啊,它一定呢会存在一个相对来说是最优的一个,呃,数组的大小的是吧?啊你过小的话呢,那就导致我们这个来回读写的比较频繁,你要说过大的话呢,我们这个占用内存空间又过大啊,那你在占用的这个过程当中,其实我们就不如小一点呢,可能频繁的去交互又好一些,就跟说大家送快递一样啊,你说快递小哥这个小车呢,要是小一点呢,小一点的话呢,它就来回的再去交互是吧,读写的过于频繁,他这个车呢,要是特别大呢,就跟一个集装箱一样啊,那他在这装的这个时间呢,就特别慢啊,有装的这个时间,他可能早都这个跑了好几趟了是吧,所以呢,呃,你要说这个本身东西呢,又没有那么多,你在这装的这个过程,那有那个时间,可能这个车适中的话呢,早都这个送完了,所以它会有一个相对的一个最优的一个选项啊。
06:51
行,那这块呢,我们看到这个复制三次的时候,大概呢,应该1.51.5个GB呢,我们是复制了三次,大概就四个多G是吧,那四个多G的这个情况下呢,整个这个时间的差距呢,嗯,不是特别的明显,诶不是特别明显,那大家呢下来呢,也可以把这个相应的这个缓冲区的一个大小呢,做一个调整,这是其一,其二的话呢,就是我们针对这个文件比较大的时候呢,他们这个效率呢,是差距呢会更明显一些。
07:17
啊,但是基本上我们能看到就是咱们使用这个直接缓冲区啊,它一定这个时间呢,是比我们这个使用IO的这个方式呢,肯定是要小的啊,就文件越大呢,它会越明显一些啊是这样的情况啊OK,这呢就是我们所谓的这一个测试啊,通过测试以后呢,我们来强调的就是直接内存呢,它的一个诶访问速度呢,是要高于咱们使用传统的方式,以及呢,其实在n ni中,N nio中我们还会讲它呢,不存在这种阻塞式是吧?诶这呢也是它的一个优点之一。
我来说两句