00:00
那接下来的话,咱们就看一看这个g map的具体的使用,那首当其冲的呢,就是它这个作用,一叫导出内存映像文件,或者呢,咱们也称为呢转出,转出呢叫堆转出快照文件啊都可以,或者叫转出这个大MP文件啊都行啊,那我们这里边使用的指令呢,就是这个杠大啊,这个指令好,那我们就来说它啊,这个导出内存印象文件呢,是咱们j map的一个主要作用啊,哎,一提到j map,大家就要想到这个作用,那这里边呢,导出分成了两种方式。一种方式呢,称为这个叫手动的方式,一种呢称为呢叫自动的方式,呃,首先关于这个内存的映上文件呢,这块我们来进行一个说明啊,呃说导出这文件是主要的指令之一,这咱们已经说过了,导出这文件里边呢,包含的信息啊,这块呢都有说明,比如所有的对象啊,所有这个类啊,垃圾回收的这个入S啊,这个咱们也可以看,其实咱们在讲这个上面的时候,不知道不知道大家还有没有印象啊,当初咱们讲这个jc roots的时候呢,我们就用了用了这个大文件,使用这个,呃,是不是MAT呢,我们当时还看了一下是吧。
01:04
好,那就说明呢,我们这个文件里边有这个,呃,这些roots啊,以及呢,我们这个相应的这个线程,还有这个,呃,局部变量表里边这个变量的一些信息啊,这是关于这个大文件的一个介绍啊呃,下边呢,还提到了说这个大文件呢,在它输出之前通常会触发一次for jc啊,所以它保存的都是fordc之后的对象的信息,那这块大家注意哈,这个主要说明的是针对于这个自动的方式。哎,手动的方式呢,你什么时候执行,它就什么时候帮你去生成这个大文件啊,咱们等下一演示,大家就知道这两种方式的这个区别了啊,下边也提到一个说生成大文件呢,由于我们这个程序呢,可能会比较大,所以在生成的时候呢,有可能会比较耗费时间啊,尤其是这个大内存的映像,生成这个大文件的时候呢,耗费的时间会更长啊,这个大家稍微注意一下就可以了啊行,那这里边儿呢,我们分别呢,给大家去演示一下手动和自动的方式,那演示的过程当中,大家其实呀也有感觉,就是它两种方式的一个区别。
02:02
OK,首先呢,咱们说一下这个手动的方式,手动的方式呢,这里边儿大家会看到,我又列举出来了两个。那这两个的主要区别呢,是下边有一个冒号live,那自然而然的这个呢,就是存活的意思,指的就是我们对应内存当中存活的这个对象,我们只保留它存活的,那上面呢,就是诶都都获取了是吧?行,那我们就直接呢来给大家演示这个手动的方式啊,去导出啊这个转出的这个,呃,内存快照文件啊,现在我们针对这个程序呢,跟咱们前面讲这个J是一样子的啊啊,我这又在这拷贝了一份放到这个j map里了,呃,这时候我们把这个相关的参数呢,咱们也给它加上。哎,把这个啊设置这个最大小的啊,CTRLC一下啊,这个我看一看有没有加。针对我们的这个j map里边的,他还没有加啊,我们加上啊好。OK,然后呢,我们现在把这个程序呢,给它跑起来,当然跑起来之前,咱们因为这个程序呢,执行一会儿它就JC这个OM了,是吧,我们先把这个相关的这个呢,咱们先打开啊。
03:03
好到这儿,嗯,跑起来,咱们得抓点紧是吧。好,抛起来之后呢,先接,然后呢我们解map,这时候呢,我们使用的就是杠damp,然后呢是一个冒号叫form me b,这个咱们一会儿呢去,哎,等于B,咱们一会去解释啊,什么意思,然后file,等于我把它保存在这个D盘下,比如说1.h,呃,Pro这个文件当中,这个对应的是幺幺,呃696是吧,好回车一下,这就生成了,然后我接着再生成一个啊,我放到一个二文件里。哎,走一下好,又生成了,我再写到一个三文件里。好再走一下,好这我生成了仨,然后呢,我们在前边这个冒号,后边呢,咱们加上一个刚才提到了是不是有一个life的一个参数是吧,然后后边呢,注意是一个英文格式,加了一个逗号啊,然后我们把它存到这个四的这个文件里。好,回车一下。行,这个时候呢,我们就相当于是生成了是不是三个这个使用咱们上边这个指令的,然后呢,生成了一个使用下边这个指令的,没问题对吧?好,那生成完以后呢,咱们直接找到我这里边儿的这个地盘。
04:15
是不是这里边对应的我们这四个文件大家就能看到了,没问题对吧?好,那这四个文件的话呢,嗯,我这儿因为之前装过这个jpo fileler啊,所以说它默认的就给我们使用这个呃jpo file呢去做识别了,那正常情况下呢,大家如果没有装,呃,你可能试图呢,想用这个T这样的一个文本文件呢,去打开,你看这时候会提示是不是有问题啊。啊,有问题,这那肯定是一个乱码的一个情况,不适合去读取了,什么意思呢?就是我们这里边儿生成的这个h pro这个文件呢,它是一个二进制的文件,哎,我们需要呢,使用特定的工具去打开。那使用什么工具呢?诶一方面有命令行的工具,就是我们下个要讲的这个解he是吧?诶这是一个工具,另外一个的话呢,就是我们后边,诶下一章要提到的一个呢,像这个j profile啊,J councilo啊,这个visual vm啊是吧,等等这样的这些工具啊MAT是吧?等等,我们去打开这个h pro这个文件啊,去读他们才行,自己看不行啊。
05:13
好,这是我们说的这个第一个事儿,然后的话呢,咱们先给大家说一下啥呢,就是刚才你看我们讲这个指令,这算是这仨其实是一个是吧,然后我们看跟这个指令里边这几个参数的一个说明哈。首先的话呢,我们看到杠大本不用多说了,你要想生成这个,对于转储快照文件就要用这个指令,后边这个叫formit等于B。这个是什么意思呀?啊,这个我们说明一下啊,这个大家需要去加上啊,它的目的呢,就是为了我们解map生成的这个,呃,这个H是吧,就是解map生成的这个文件呢,跟我们这个H这个格式的文件呢,它能够去匹配起来,能够使得呢,咱们用刚才提到的那些图形化界面这个工具呢,去识别你这个格式的文件打开啊,就是表示呢,我们这个格式呢,你得是一个标准的格式啊,啊这是说的这个参数的意思,后边呢,不用多说了,就是你把这个文件呢,要保存的位置在哪,针对于哪一个Java进程的。
06:11
对吧,这个应该很清楚,好呃,这是我们说的这个事儿,然后呢,大家会看到另外呢,我是不是又呃,在整个这个程序执行的过程当中啊,为啥刚才着急写呢,我是怕这个程序呢,就一会儿就结束了,是吧?哎,在结束之前呢,我希望呢,把整个这几个事儿呢都做完,大家呢,你会发现随着我们这个程序的一个执行啊。啊,你看随着这个程序的执行,是不是说我们这个你看文件的大小是不是越来越大呀。对吧,诶大家会发现这个文件呢,它就越来越大啊,这个呢,就是因为我们这个随着内存的不断去执行,我们相关的这个数据呢,是不是也会越来越多呀,哎,这是这样个情况啊呃,当然这里边的话呢,我们看到这个四啊这个冒号live这个文件呢,也变大了。啊,也变大了啊,因为这就跟我们这个,呃,这个实际这个过程当中,这个存活的对象多也有关系哈,呃,这个live是什么意思呢?哎,刚才呢,我们在这个课件里边,其实上边有一个说明,它呢是只保存咱们堆中存活的这个对象。
07:15
啊,就是大家在实际生产环境过程当中啊,我这块演示的时候,大家会看到它是变大了啊,这是跟我们这个呃,它回收的这个节点有关系哈,那实际在生产环境当中很有可能发现,你要是用这个冒号live呢,生成这个文件呢,它是可能会变得更小的。啊,可能会变的更小的,这个大家呢,你下来自己去做一个演示啊,就能看到这个情况啊呃,那这想说明的问题是什么呢。就是我们在开发当中,到底大家呃,是应该使用上边的指令,还是应该使用下边这个指令呢?哎,应该有这样的一个解释,哎,这个大家注意啊,听我说啊,听我说啊,嗯,就是我们生成这个大文件呢,刚才咱们这个程序呢,比较小,呃,生成这个大文件呢,也就几十兆是吧,在实际的生产环境当中,我们生成这个大文件呢,可能达到哎,几百兆。
08:04
哎,可能有这个几百兆,那如果说呢,是有几百兆这个大小,那大家呢,你让这个相应的这个运维人员从这个生产环境当中给你这个脱下来是吧,然后再传给你,然后你呢,再使用这个比如说VSOVM呢,去打开这个单文件,因为这个文件比较大,打开呢,是不是花费的时间也会多一些是吧?那打开之后呢,你再去分析到底是什么原因导致这个整个生产环境中出现这个OM了,或者这个内存这个比较紧缺的这个情况了,是吧?哎,那这时候有可能这个半天时间就过去了。哎,半年时间就过去了,那我们加上这个,呃,Live这个参数之后。诶,这个时候呢,我们是不是只打印这个堆应内存当中存活的这个对象呀,对吧?呃,只抓取这个存活这个对象,那这时候呢,哎,我们呢,这个相应生成这个文件呢,是有可能变得就会更小啊,然后这个变大了是因为跟我们这个程序是有关系的啊啊它有可能就会变得更小,那这个小到什么程度呢?有可能是降低一个数量级,那就是只有这个几十兆啊,只有几十兆的一个大小,那这时候呢,如果你再呃通过这个运维的人员再给你推下这个拖下来,拖下来再发给你,然后你再打开使用这个VVM啊等等工具打开的时候呢,这个速度也会更快。
09:17
啊,就赢取了这个排除这个故障的一个宝贵时间啊,因为我们会发现呢,在实际生产环境当中,哎,我们去分析这个数据的时候呢,多数情况下呢,也都是由于我们这个呃,JC回收不走的这个对象呢所造成的啊你像OM不就是JC没回收走嘛,没回收走意味着它还存活,所以呢,我们更关心的就是这个存活的迹象,所以大家呢,在生产环境当中,呃,多数情况下呢,我们就没有必要使用上边这个了,而是使用下边这个冒号live啊去打开就可以,呃去获取这个大MP文件呢就可以了。能理解这个事儿是吧?好,那这里边儿呢,相当于通过刚才我这样的一个演示,包括说明大家需要记住的点啊,记住的点应该是这两个有什么区别对吧?以及呢,生成的这个大文件呢,咱们是不可以直接呢去通过通过这样的一个记事本去打开的啊,它是一个二进制的一个文件,需要使用特定的这个工具啊。
10:10
好,然后下边呢,再给大家说明一下这种自动的这个方式该如何进行设置,哎,自动的方式哎,大家看这里边所描述的啊,说当程序发生OM系统推出的时候呢,呃,一瞬间的这个信息呢,都会随着程序的终止而消失了,那我们要想重现这个OM问题呢,就会比较困难啊,或者叫耗时,怎么办呢?如果能在发生OM的时候呢,我们自动的去导出一个大文件呢,就显得非常的迫切。啊,显得非常迫切,所以这里边儿呢,我写的是手动跟自动,严格意义上来讲呢,它算是两种不同场景下的一个使用。大家想想对吗?什么意思啊,你看我们上边这个生成这个大文件的时候,我是不是一执行这个指令,它立马就帮我们生成了。当然我说的这个立马指的意思就是说没有等待我们出现OM啊,我们这个程序呢,没出现OM的时候呢,我不是就生成这个文件了吗?哎,也就是说这个手动的方式呢,就是针对你当前这个场景来帮你去生成当前场景下的一个内存快照文件。
11:09
而我们下边这个所谓的自动方式呢,它只会在你最后要报OM的时候呢,诶赶紧帮我们生成一个大文件啊,它其实叫手动自动的,这个方式呢,可能会误导大家,好像叫二选一,但其实呢,它针对的场景也是不一样的。啊,针对的场景不一样的。注意啊,注意我刚才说这句话很重要啊,相当于我说清楚了,就是我们到底什么时候用手动,什么时候用自动,他俩的一个对比啊,就是当你要程序出现OM的时候,我们希望去监控这一刻的,呃,这个程序的一些数据的情况,那我们就需要用自动的方式了啊,因为你不可能恰好这个时候呢,手动执行了一下是吧?哎,这个注意啊。那这个自动方式怎么去做呢?这里边儿需要大家去配两个参数啊,一个呢,就是诶我们关于这个堆的一个damp,当我们这个OM的时候,我们是获取一下这个damp,哎,所以你看这时候它执行的一个时机非常重要啊,下一个呢,就是你指明通过这个参数啊,指明到底是存储在哪个位置啊,这是我们通过这个参数来指明的,行,那就比如说呢,我们有这样的一个设置是吧?哎,或者说你你从这粘也行哈,这一个CTRLCL一下。
12:16
回过来看这我们就出现OM了啊,我们在咱们当前这个程序的后面啊,我CTRLV一下粘一个,然后再来一个。啊,CTRLC。那到这儿我再CTRLV一下是吧,嗯,这块呢,咱们把它就也改一下这个具体的存储的路径哈,比如我就存储到这个D盘下的,刚才咱们12345来个五吧,哎,这样个文件里边,好,然后OK一下。嗯,这个让这个让这个程序呢,执行的稍微的快一点啊,咱们这块比如说改成这个60吧。好,把它呢跑起来。哎,跑起来了,好,这时呢,我们打开咱们这个D盘啊,你看此时的话呢,咱们这个位置呢,1234是咱刚才手动生成的这样的四个h pro这个文件,哎,我们看一看,现在这种自动的方式并没有在我们程序执行过程当中去,我们生成一个或多个这个文件。
13:09
啊,而是呢,在最后出现OM的这个时候呢,才会出现啊,才会帮我们生成h pro这个文件啊,我们稍等一下。哎,这个我们把它这个改成60毫秒啊,实际上还可以改的再小一点啊,让它比较快的去生成这样一个,哎。H文件。好了,大家看这时候呢,我们出现了这个OM了,在出现这个OM的这一瞬间呢,大家会注意到我们是不是这个文件就生成了。哎,生成了是吧?哎,大家也会发现呢,就随着我们这个程序的执行的越来越多啊,你像我们现在才执行的也就几分钟,最多是吧,这样就生成了50多兆,那如果你这个程序呢,执行了好几天,甚至是非常多的几个月的时间,你能想象一下我们这个h pro这个文件呢,是不是相应的会很大呀,哎,所以呢,我们刚才提到这个冒号live啊,这个是非常有必要的啊,这个大家注意一下行,那这样的话呢,我们就自动的是不是生成了这样一个文件。
14:09
啊,那么这个呢,是咱们咱们出现OM的时候出现的,所以我们更关心的就是OM到底是什么原因造成的,所以我们通常会针对这样的一个文件呢,进行一个分析。啊,对这个文件进行分析,因为它的时机很重要啊,OK,那么关于手动和自动的方式,通过我刚才这样的一个演示,大家是不是自然而然的也就知道他俩的一个区别了。它俩的一个区别,刚才也说了是吧,这两个的区别是不是也说了,哎,就是在OM的时候呢,让它生成的这个MP文件啊,那另外呢,想说一个问题呢,就是呃,有的时候呢,我们这个程序呢,可能比较大啊,比较大的时候呢,呃,你要是用这个自动方式,有可能它会出现一些问题啊,呃,有可能会出现一问题,所以呢,大家呢,在我们这个程序执行过程当中,这个实时的通过这个手动的方式去获取一个h pro文件的这种方式也是需要大家掌握的啊。
15:01
嗯,好,这个呢,就是关于导出内存映像文件的这样的一个演示,大家呢自己呢去操作一下啊。
我来说两句