00:00
好,那在说完这个直接内存它的好处之后呢,咱们来看一下下边的内容啊,这块呢,提到了说这个直接内存啊,它也有可能会导致OM这样的异常啊,是也有可能会出现OM的,那我们来看一下说由于这个直接内存啊,它是在Java堆外的,因此啊,它的大小呢,不会直接受限于我们堆空间的这个杠XMX就是这个堆的一个最大的内存,它指定的这个值的一个影响,这个很显然了,对吧,因为呢,它本身呢就是不同的结构,虽然说呢,咱们在Java虚拟机规范中提到了说这个呃,堆空间从逻辑上呢,是包括这个圆空间的,但事实上呢,我们说圆空间呢,也不受这个堆空间大小的设置的一个影响啊,再加上这圆空间呢,只是属于我们之间内存的一部分是吧,这样的就是它的它俩个其实没有任何关系,所以不会相互之间影响啊,但是呢,这个由于我们说这个系统的内存啊,其实也是有限的啊,所以说呢,这个直接内存呢,它的一个大小,就是说如果你超试图呢,超出了我们系统内存这个。
01:01
可以有的这个空间的话呢,它照样也会报一个OM,那也就是说咱们这个堆空间和直接内存的总和呢,你还是要小于咱们系统能给予你的一个最大内存的,这个毫无疑问是吧?诶这个大家应该很好理解啊,呃,那事实上呢,就是这个咱们Java这个服务器管理员呢,他在分配这个内存的时候呢,呃,经常的话呢,比如我们在分配这个堆空间的时候,呃,就只是呢,会考虑说这个堆空间,我们呢要呃根据这个系统能给予的这个最大内存呢,我们去设置相应的一些堆空间。对吧,那其实就忘了呢,我们程序呢,其实在使用过程当中还会有这个直接内存的一个存在啊,那包括呢,咱们还有其他的一些,比如说你这个处理器的寻址空间的一个限制啊,包括这个分页文件啊等等,都会占用我们相应的本地的一个总内存啊,所以导致的就是我们在分配的时候呢,就忽略了这个直接内存,结果导致呢,把对内存分配过大啊,导致呢最后我们直接内存在使用的时候呢,空间不足啊,直接呢就报了这个OM,所以这个呢是大家呃需要特别注意的一个点啊,需要特别注意个点行,那这呢,咱们也给大家举一个例子哈,呃,这呢写了一个呃,Buffer test2嗯,这个代码的话呢,仍然不是说特别复杂,我们给大家呢,直接来说明一下,呃,这个是20GB啊,我这呢是一个release,然后呢,我不断的是使用本地的一个呃地呃,本地的一个direct by buffer空间啊,这个空间的大小呢,就是2GB不断的去添加到咱们这个release当中,就避免了我们被JC是吧?哎,这有一个well处啊,那最终的结果。
02:32
那就是导致我们这个程序呢,出程序呢,出现了一个,呃,直接内存就挂掉了啊这个外处的话呢,你往这放,这肯定禁不住放是吧?好我们把这个程序呢,给它抛起来,我使用这个sleep呢,实际上这个过程呢,稍微的缓和一点,顺便的话呢,我们试图呢,注意你看我这时候要试图是吧,使用我们这个接VVM呢,我们打开看一下。这呢是咱们当前这个进程。打开,然后呢,你可以看这块监视这个显示的堆,这个叫Meta space。
03:00
嗯,然后JC这块呢,其实你就别指望了,咱们这块呢是看不到的是吧,这呢也只是咱们这个麦达pace,它属于我们直接内存的一个部分而已哈,行在这块呢,呃,Metapace这块其实我们也看不到,说关于这个直接内存的一个情况啊,就是使用它呢,是这样子的,包括呢,咱们要用这个接profile啊,也是同样的道理,那这块呢,其实我们已经看到这个异常的情况了啊,如果说我们这个直接内存要是超了的话呢,这块呢报的也叫OM,叫direct buffer memory啊,这也是我们出现的异常,大家关注一下。那是这样的一个异常的信息,Direct buffer memory,咱们讲这个OM呢,是不是已经遇到过好几种情况了,OM呢,有这个hi space,有Meta space,有这个呃,Pro pro space是吧,就是我们这个永久贷啊,这个还有呢,我们这里边叫直接的一个缓冲区啊,都会出现这样的OM啊,那么在面试当中呢,也会问你说这个OM呢,你见过几种OM呢?啊,除了我们说的这几种之外呢,还有其他的一些啊这个呢,以后呢,我们再给大家去讲啊行,这呢是我们说的这个问题,一共呢,是循环了181次啊这呢是记录一下这个循环的一个次数,那你也可以呢,使用咱们所谓的叫j pro是吧?哎,用它呢,打开试图呢,想查看一下能不能,呃,监控到我们这个直接内存它的一个移出问题是吧。
04:24
真的是一个memory的一个情况,这个是一个堆的占用,那我们看这个非堆的一个占用,那其实这块呢,显示这个空间呢,是不足的是吧,那就这块显示的不是很准确的啊IG呢,我想强调的问题是什么?就是不管我们是用这个j pro也好,还是使用JVSOVM,还有j conso等等这样的工具呢,咱们实际上是监控不到这个本地内存它的一个占用问题啊,你要非要想看的话,你可以考虑呢,在咱们这个任务管理器这块呢,大家可以看一下这个内存它的一个占用情况。在这来看一下是可以的是吧,在这看一下可以的哈,呃,想强调的问题是什么呢?就是如果咱们的这个程序当中,大家呢,在运行的过程当中,最后呢,程序报OM了,报OM的时候呢,我们说到底什么原因造成的,当然有可能是你内存空间分配不足,当然你变大以后呢,照样也出现了,那我们呢,就会有这个叫大文件嘛,你把这个dump文件导出来以后呢,使用要要么呢,你是用的eclipse呢,叫这个mitt是吧?哎,使用这样的一个工具,那或者的话呢,你是用咱们说的j pro也好,或者用这个JVIVM也好,我们去查看这个大文件的时候呢,发现这个大文件呢比较小。
05:31
啊,呃,又出现了异常,这个文件呢,又比较小,这时候呢,你就要想你在程序当中是不是直接或间接的你用到了这个,嗯,Direct buffer就是我们这个本地内存啊,典型的就是咱们这个NIO的场景,那极有可能是由于这个本地内存呢,最后呢,呃,出现的问题,因为我们在这里边呢,是看不到本地内存它的一个呃,占用溢出的一个情况的,是吧?哎,你考虑一下这个问题啊,这个大家需要注意一下。行,张老师,我们说强调的这个问题啊,呃,那然后的话呢,嗯,咱们再来看。
06:04
呃,这呢是提到说这个也照样会出现OM,那缺点呢,就是说我们关于这个直接内存它的一个分配回收的成本啊,是比较高的啊,一般的咱们这种直接内存里边这个数据是吧?那这个回收的话呢,如果是像源空间,它属于这个回收的频率呢,也很低,那我们在回收这个不用的这个类的时候呢,咱们前面也讲到过了,是不是层层的进行一个判断,而且判断完以后呢,最后还不一定能回收是吧,导致这个成本比较高,另外呢,咱们扎va逊尼这回收管理呢,呃,也没办法直接呢去操作咱们这个直接内存啊,除了我们说这个呃源空间之外是吧?呃,如果我们在程序当中使用了本地内存的话呢,我们也不能方便的去进行一个直接的回收管理,所以导致呢,就是我们这个直接内存呢,咱们监控起来就比较有难度,咱们大文件里边呢,也不会做一个记录行,这是这个问题,那么既然你会出现OM,我们在想一个问题呢,就是说我能不能去设置关于这个,呃,对空间的一个大小,那这个直接内存那个大。
07:04
好啊,这说呢也是可以的,这个大家也是了解一下,我们通过这个叫max direct memory size啊,使用它呢,来设置一下咱们这个直接内存的一个最大的值。哎,它的一个最大值,那么这个值呢,如果咱们要是不指定的话呢,诶默认情况下呢,和我们对空间的这个最大值啊XMX这个参数的值啊,是一样大小的,哎这个呢,一说大家哎一听哎记住了,了解了就就OK了是吧?嗯,那么最后呢,还有一个程序哈,这个也是简单说一下,这个程序的话呢,是深入理解扎瓦虚拟拟里边啊这本书当中的一个例子,哎,这本书中的一个例子啊嗯,这个例子呢,实际上是这样的啊,你看我这呢,是不是通过反射的方式呢?诶调用获取到了我们这个unaf里边的一个指定的属性是吧?哎,指定的一个属性,那这呢,提到一个unaf这个类,这个类的话呢,实际上啊,实际上是咱们前边是不是说的这个叫bad buffer呢,在底层调这个aocate direct的时候呢,我们是不是创建了叫direct by buffer呀,而这个direct by buffer里面它是需要呢,来诶创建一个unaf,也就是我们这个Una这个类的一个对象的,说白了就是我们前面写的这些例子啊,一个两个三个这些例子当中。
08:14
我们是内部通过direct by buffer呢创建了一个UN的对象。是吧,诶创建了一个unif对象,那我们这个例子呢,是直接呢,通过反射的方式呢,我直接呢去获取到了这个unif的实例了啊,以及呢,就是我们拿到这个实例当中,诶这个还到没有具体做到它的对象,只是把它加载到内存中是吧,然后获取到它内部的一个属性来去做了一个调用,然后这个时候呢,我们通过这个UNS看原来的时候呢,我们是在这里边,你uniff呢是a locate一个memory指定那个大小,而这个例子当中呢,是不是直接呢去分配一个大小啊,就是绕过了这个,呃,Direct by打粉是吧?嗯,那这呢是一兆,然后通过一个while处的方式呢,不断的去往里放啊你呢也可以呢,去把这个参数再加上设置一下我们最大的一个direct memory size。
09:00
啊,这个大家其实设置也好,不设置也好,那你是个外处的情况,那肯定会移出嘛,对吧,那这块咱们也可以确实呢,给他加上啊好,我这呢做一个edit。嗯,在这里面选中咱们刚才说的这个程序呗,然后在这是吧,CTRLV1下行,然后。嗯,Already啊,这个是我们说这块已经存在这个删一个啊行,然后apply OK,那设置完这个参数以后呢,我们直接呢这块去运行,这肯定运行呢,有一个明确的上限了啊,就十个兆,哎,很快的就会出现我们这样的一个异常信息。啊,这样一项信也是一个OM的情况是吧?哎,那主要针对就是我们这个第二行。行,那这呢就说清楚了啊,那通过这个呢,咱们想说明的点呢,就是说那一个呢,直接内存它也会OM啊,为什么会有M,平时我们需要注意的问题呢,就是大家也要注意,咱们直接内存呢,它也是存在的啊,你在分配堆的时候呢,还要兼顾到直接内存啊,别分配的这个太多了,导致这个呢不足了,要想显示的分配它的话呢,我们使用这样一个参数默认的时候呢,跟我们这个对空间的最大值的值是一样子的啊,这就可以了。
10:07
行,那么说到这儿呢,整个关于咱们这个直接内存啊,咱们也就介绍到这儿啊,也就介绍到这儿啊,那比较简单的一个理解呢,大家就可以把我们这个,呃,所谓的这个进程中所占用的内存空间,就理解成是堆空间,加上一个本地内存就可以了。是我们Java程序的这个角度对吧?呃,像这个虚拟机站啊,呃,等等啊,程序计录器啊,它那个空间就太小了,诶直接呢,我们就可以认为呢,程序当中,我们Java程序当中就是堆空间加上一个本地内存,就整个构成了我们Java程序进程的一个,呃,内存的占用啊行,那整个这一章呢,大家做一个了解就行。
我来说两句