00:00
行,那咱们再再今天再看一下啊,我们看一下我们这个程序的一个执行的内存是如何变化的啊,就在这块我们看一下方法执行过程中内存是如何变化的,好吧,那这块呢,我去写一个程序啊。METHOD08呀。好,我们把这个给他。代码我先写一下,各位啊,代码先写一下。叫method test0808public。Static。然后呢,这个呢是主方法是不是啊是入口,那么现在呢,在这个方法里边,我们这样去调一个方法啊,这个方法叫M1。M1方法呢,有个参数啊是I,然后呢,我在这这块呢,又去调一个方法。这个方法呢叫M2啊,也有一个变量I,然后呢,接下来这里呢,有一个方法,这个方法呢叫M3方法,那也有一个变量呢,叫做I,然后接下来我们在这里干什么呢?定一个I等于多少啊100,然后接下来M1啊,我把这个一把这个I呢传进去,把这个I呢作为参数传进去啊,传给这个I。
01:19
把这个I传到不是不是传给这个I,把这个I呢,传给这个方法啊,或者给他起个名叫X吧,X啊把X传进去对吧,把X付给了谁啊,付给了这个M1方法,那么这个M1方法这边有一个int类型I嘛,那把X是不是就附进去了。是不是哎就附进去了,附进去之后怎么办呢?哎,我们在这怎么着啊,大家注意看啊,system.out.line打印输出,我们输出一个men begin。然后在这呢,system.out.line打印输出叫manover。啊,然后呢,把这个复制一下啊,这个呢,我们叫1BEGIN吧。
02:00
1BEGIN啊,1O。Meo啊,然后呢,在这块我们去调一下。M2啊,然后把这个I再穿进去。你看啊。这样吧,这个这个这个这么这么写吧,啊,然后呢,Int I把这个I呢,作为参数传给谁啊,M2M2这是不是需要一个T呀。对不对,哎,需要int把I传进去了,传进去了啊传进之后呢,呃,我们接下来在这呢,同样也一样啊,叫做mmr的一个begin,我们把这个内存图分析一下啊,M Mr begin,嗯,然后M2OVER。M2OVER啊,然后M3。啊,把这个I放进去。放进去啊。嗯,然后呢,这边是把这个叫M3的一个啊。
03:04
M3BEGIN,然后呢,输出这个I的值。啊,然后呢,再输出M3的一个over啊M3OVER好大家看这个程序是这样一个程序啊,我们把这个程序的执行过程用一个内存图的方式给它表述出来,好吧,用内存图的方式表示出来啊来再看这是一个类呗。是不是啊,这是一个类,然后呢。我们这是一个代码对吧,先执行问方法吧,问方法先说出这句话吧,是不是生命的变量啊,这是个生命变量吧,局部变量,然后接下来调这个方法M1吧。嗯,调这个M1方法啊。那么M1方法呢,在这儿执行是不是啊,执行又去调M2,然后呢。M2这块怎么着啊,输出还去调M3啊,然后大家看我现在先问一下大家啊,这个X变量A变量,还有这个I变量,还有这个I变量。
04:00
我问大家,这是。这是几个局部变量。这几个局部变量内存一样不一样。是同一块内存还是四块不同的内存?什么叫局部变量?各位?局部变量就意味着这个变量只在这个方法里边有效,对吧。方法执行结束之后,这个变量内存值就释放了。对不对。哎,所以这块要注意啊。局部变量啊。局部变量只在方法体重有效啊局部变量。只在方法体中有效。有效啊,方法结束之后。啊,局部变量的内存就释放了啊,局部变量内存就释放了,注意啊,呃,JBM3块主要的。
05:02
内存是什么?是占内存,还有一个叫什么堆内存,还有叫什么方法区内存是不是来再说一下方法区,方法区最先什么有数据啊,方法区中放什么。方法区中放代码片段是不是啊,代码片段代码片段啊啊存放class自解码啊,这是方法区,堆内存呢,堆内存呢,堆内存后面讲啊后面讲,然后还有叫什么占内存吧,哎,占内存。占内存是方法调用的时候。啊,该方法需要的内存空间在占中分配。注意啊,方法调用的时候啊,方法调用的时候,该方法就是方法调的时候,它这个方法所需要的内存空间是在站里边分配的。
06:04
啊。方法不调用。是不会在。占分配空间的。啊,方法只有在调用的时候才会在。占中分配空间。并且调用时。啊,就是压站啊这段话方法执行结束之后,该方法所需要的空间就会释放,此时发生什么呀,弹战动作。啊,我不知道大家理解不理解这个啊,什么压站谈战,还记不记得我们刚才画的那个图。
07:01
是吧,啊,这个图是什么呀。我们是不是又说了一个数据结构叫占呀。对不对,哎,说了一个数据结构叫占啊。那么当你这个方法调用的时候啊。他这个方法所需要的空间。就你这个方法调一个方法,你的方法需要活动场所吧,你这个方法所需要的内存空间会在占中分配。啊,你你调一个方法,他就在这分配给给这个方法分配一块空间。你调用另外一个方法,它就会在这里继续分配空间,这个这个动作叫什么?这动作叫什么?叫压站是吗?好,那你现在这个方法所执行完了,假如说你这个方法执行完了,那你这个方法所之前所分配的这个空间是不是就释放掉了,那么这个时候是不是就发生一个叫谈战的一个一个一个一个动作呀,对吧?方法我再强调一下方法,如果你只是去写到这儿了。但是你没有去调这个方法。
08:01
那么这个代码只是在哪存放?各位给我互动一下这个代码,如果方法只是只是写上,没去调用这个代码片段是在哪的,这个代码片段都是在哪的代码。在哪个区?方法区是不是,哎,只有说你这个代码这种东西啊,你是是你方法是写好了,但是我要去调你这个方法对不对,哎,我调你这个方法的时候,你这个方法所需要的空间活动场所,它就会在站里边分配。啊,站里边分配你,你调一个就是就就压一次什么意思,你调一次就往里边压一次,你调一次就压一次,你这个方法执行结束之后,空间释放你得弹一次。啊,所以说方法结束叫谈战,方法调用叫压战。注意啊,注意。方法调用叫做压站啊,就就就是分配空间啊,然后方法结束叫做谈战啊,就是就是释放空间啊,释放空间一个是一个是压,一个是弹,压站这块就是分配空间,给这个方法分配,谈战就是这个这个空间就给它释放掉了,因为方法结束了呀,哎,方法结束了啊,要知道这个关系啊,知道这个关系那三块里边到底都存什么方法区存啥堆内存里边没说啊,后边讲占里边存什么。
09:24
对不对,哎,这里面存什么。那么这里面到底存什么?各位来,各位,我问大家问题。既然。方法在调用的时候会给这个方法分配空间,那我问你这个I变量是不是就在站里边存着呢。将来在调这个方法的时候,这个I变量是不是一个局部变量,这个局部变量它所需要的内存空间是不是在占中分配啊。是不是在战中分配啊,对吧,所以站里面存什么呀。中存储什么?方法的。运方法、运行过程中需要的内存以及。
10:03
占中会存储什么局部方法的什么局部变量啊局部变量,所以刚才那个图呢,我们又可以给他改一下。哪个图呢?就是刚才画的那个图啊,我们找一下在哪儿啊在。这个地方呃,应该是有一个图是吧?站,嗯,不是这个应该是这个啊,我们打开方式用一下这个画图工具打开,就这个站里边它存什么呢。你将来会发生一个动作叫什么呀,压站。是不是,哎,压榨。这个呢,就是那个方法所需要的空间啊,方法执行需要的什么啊空间啊。另外,这里会存储什么?该方法的什么局部变量?就变了。啊,所以这块呢,它存的是什么呢?存的局部变量。
11:02
啊,这是一个方法啊,这是一个方法,再调一个方法,你就会再压过来一个,再调法就会再压那个,这个方法结束之后就弹出去啊是这样来,我这个呢就关掉了啊关掉了,那对于这个呢,咱们提前先说一下,然后我觉得我这个图才可以去画,刚才的这个呢,是个局部变量X,我问大家这个X在这能不能用啊。你在这访问这个X变量,在这个方法里面访问这个X变量能不能用啊,不能用,我们很早就说过了,这个X呢,是一个局部变量,只在方法体重有效,方法结束之后,我们,诶这个内存就释放了,所以在这个地方我们是访问不了的,是不是啊访问不了的,那么接下来我们把这个图画一下,各位啊。来,咱们一点点画,一点点画。来,我往这儿拖一下啊,往这儿拖一下,这个往这儿拖一拖啊,往这儿拖一拖。来。往这点啊,咱们先保存一份,保存一份啊,方法执行过程中的内存变化啊,叫做方法。
12:06
执行过程中的内存变化,首先我们先画个大点的啊,大点的这个东西呢,我们就给它想象成是什么呢?哎,叫做一个JVM,各位啊。JVM,那么这个JVM呢,这块啊,它有一块空间是不是,哎,这块空间我们叫什么呢?叫做。方法区啊,方法区啊,还有一个空间叫什么呀。叫堆内存是不是,哎堆内存啊堆内存。这个以后存什么,到时候再说啊,在这个Java虚拟机里边还有块空间叫什么叫做哎占内存是不是,哎占内存啊占内存我我画成这样吧,画成这样啊,这个叫做什么呀?Stack啊站那么这个站呢,这个顶部这块啊,咱们是。是没有的啊,咱们删掉它。
13:02
然后接下来呢,首先啊,我们这个程序执行的时候,他会先把我们这个这个类啊,它整个这个类的代码,就是整个这个这个东西的代码过来。啊,放到哪儿呢?他会把它放到我们的方法区里边。啊,方法区里边,所以这块呢,它会进行类加载啊,它存一个什么呢?它存一个这个叫做method test08的class。点class啊,点class代码片段。啊,就是代码信息,代码信息啊,然后比如说问方法是不是,哎,然后呢,外边是类的信息。哎,Class叫method test08,然后零八,然后这块呢,是一个闷方法对不对,哎,然后闷方法这块又去有一个什么M1方法是不是,哎,我大概要画一画啊这个代码啊,然后M2方法是不是哎。
14:02
M2方法写直接写一下啊,还有M3方法等等吧,来来在这儿省略号啊,就是说我们首先要知道啊,这个方法区里边存的是什么呢。哎,方法区里边存的是我们的一个代码片段,就是代码片段啊,代码的片段,那么堆里存什么,以后再说啊,以后再说,那这个代码装载到我们的方法区里边之后呢,就放好了,接下来我们开始执行了,那么只要我们Java虚拟机执行,那先去调的是这个闷方法。它会去调用这个闷方法啊,我们说了,只要调闷方法,就会给这个闷方法分配空间,对吧?啊方法会先去执行闷方法,只要调用这个方法就会在在哪啊在站中分配空间,所以在这个时候呢,他会给在站里边压站。啊,会在这儿压站。压榨,那假如说这个呢,就是我们的一个焖方法的一个,哎,我们有专业术语啊,叫焖方法啊,战争啊焖方法战争。
15:02
这就是那个闷方法战争啊。好,这个闷方法给它空间给它分配出来了啊,分配出来了,分配出来之后呢,哎,首先呢,大家看这里会输出一个什么呀,叫闷。简begin什么意思,就是说我们这啊这个抽象抽象派的啊,画简单画一下。画一下啊来,那么这块呢,它会去输出一个什么呀,叫做什么begin。啊,Man begin颜色的话,我们用一下这个颜色吧,啊,Man begin。输出这个,那输出begin之后呢,接下来有个类型的X等于100。这个in特向X等于100是什么意思?就相当于啊,它这个局部变量就会在这儿分配,分配一个空间。对吧,哎,分配一个空间,比如说在这儿呢,哎呦,画的有点太小了。在这儿啊,有一个X变量。X变量等于多少呢?哎,100。啊,会有这么一个数据,各位啊,会有这么一个数据,那么接下来干什么呢。果然小了。
16:01
哎呀。改改。改改啊。我上。上行。我的天呐,这种图。很煎熬,你知道吧?好。那么我们再往下的话,就调M方法了,是不是调M方法进去啊把进去,那么这个时候呢,我们在这里会调这个方法。关键是你这个方法一旦调用啊,它就会给这个方法分配空间,你懂吧,所以呢,程序它就会停到这。听到了。啊,黑色吧,停到这儿,停到这儿之后怎么办呢?它往下就不走了,因为你去调了一个方法,这个时候呢,他会在这个站里边干什么呀?哎,分配一个新的空间。啊,这个空间是谁的呢?哎,就是这个叫做M1的。
17:00
一啊,方法啊,占帧,那么我不知道大家还记不记得我刚才是怎么说的,在占顶部的元素具有活跃权,还记得吗?就是谁在站的顶部啊,现在是M1方法在占的顶部,是不是,他是不是具有活跃权,问方法是不是暂停啊。那他为什么进来了呢?是因为我这是不是掉了M1方法,掉了M1方法是不是把这块内内存空间就压过来了。对吧,啊,就相当于这块空间就压过来了,压过来之后呢,谁在占顶部,谁具有活跃权,下边这个门方法它活跃不了,他停下来等待谁呀,等待我们M1的执行,而我们M1这块有没有in各位。这个位置是不是有个I变量。I变是不是局部变量啊,所以这块是不是有一个哎因特I。对吧,哎,那么这个I等于多少呢?因为你是把X传进去,还记得吧,哎,把X传进去就相当于把X给了这个I就是X。负值给谁呀?给这个I,那么就相当于是不是把X里边所保存的这个数,X里边保存是100吧,是不是把100复制了一份传给了M1。
18:08
所以这个是不是也是100。对吧?哎,这就是100,各位啊,这就是100,但是这个100和这个100不是同一个100,我说了你把X传给了M1,实际上是相当于把X里边保存的这个数据100传进去了,那这样的话,我我这个M1方法这块,这个是个局部变量,各位这是I是局部变量啊,I是局部变量,那么这个时候呢,我们呢,这个哎100传过去给了这个I之后呢,再往下就是M1干什么呀,Begin了呢,是不是,哎在这块呢,其实就是M1BEGIN。M1BEGIN啊就输出了,那输出之后呢,接下来干什么呀?哎,接下来再往下就掉了M2。是吧,那他又去调了M2,也就意味着这个位置它实际上是调了一个M2。那当我掉了M2之后呢?同样的一个道理是什么呢?是程序会停下来。
19:02
会停下来,停下来,因为掉了方法,所以呢,它会导致一个动作,什么动作,就是压站的动作啊,这个画的有点小了啊,有点小了,一会儿咱们再再补一补啊,再补一补来。哎呀,是那回事儿就行了,各位啊,这个呢,其实就是那个M2方法的战针啊战争。战争啊,M2方法的战争。那么这个M2方法战争呢?它现在又处于什么呀,我们的一个站顶部了,我说了处在站顶部,为什么呀,因为你在这儿掉了嘛。调这个M2呢,M2现在M1去掉M2 M1就停下来,M2去执行了。你明白吧,现在去执行了。啊,那M2现在同样一个道理,M2这边呢,输出m Mr begin。但是M2这块有个局部变量int I啊。那你是不是在M1执行过程当中调这个M2 m2是不是把这个I又给他传给了这个M2啊。
20:02
所以我们这个M2的TI在这个位置的一个值,我相信大家应该也能知道它是多少啊,是int I等于多少啊,一百八是不是哎,100,然后紧接着M2是不是begin啊。对吧,哎,所以这块呢,是不是就输出一个M2的一个begin呢。对不对,M2BEGIN之后怎么办呀?哎,M3调用了。那M3调用就是在这儿呗。是不是,哎,M3调用。那么调用这个M3方法这块还很有意思,怎么着它又停下来了。是不是啊,停了干啥呀,压站呀,又压过来一个。对不对,哎,压过来一个这个呢,哎呀。这图。画的。能看懂什么意思吗?这是。那这是站顶部啊。再补一块儿。行吧,哎,这个呢,其实就是我们的一个叫做M3是吧,哎方法战针啊M3方法战针。
21:08
那么,那么这个M3方法战争,它现在处于站的顶部。是不是,哎,为什么呢?是因为你在这儿掉的吗?调到M3 M3方法呢,所分配的空间就在这个地方分配了。啊,分配之后占顶部元素具有活跃权,那么M3方法就开始执行M3方法输出M3BEGIN。啊,M3:1。在这呢,就输出了M3BEGIN。然后紧接着呢,输出之后呢,再往下,其实就是。I的值输出了,但是这地方有个int I是个局部变量,是不是这个I也等于多少啊,哎,因为把这个I不是这个I是100,不是传进去了吗?所以这个I呢,也是多少啊,也是哎100,其实我应该怎么着呢,应该把这个M3。给它写到下边上来,实际上调M3的时候就传过去了啊int I等于多少啊来100,那这个100呢,实际上是传过来对不对。哎,然后在这个位置怎么着呢。
22:02
M3 begin呗。M3 begin。然后紧接着是不是输出了一个I。在这输出了吗?哎,在这逗号呢,各位啊,逗号输出什么呀,哎,100。加逗号啊,这个实在是没法画了啊。我应该少画俩方法。M3BEGIN输出100,输出100之后呢,M3就over了,也就是说这边呢,它再往下就是M3的一个over啊over。因为这个方法结束了呀。对吧,哎,所以这个是不是就谈战了。是不是,哎,M3方法执行结束就弹出去了,弹出就它就露出来了,它露出来之后它就有活跃权,那这样的话,M3I这行代码就结束了,再往下是不是就输出M2O。
23:02
是不是,哎,在这儿是不是就有一个叫M2OVER的一个东西啊。哎,放这啊。Take m r over。那当M2之后呢,接下来大家应该能想象到,我们这块的空间是不是就结束了,因为你M2OVER这一输出,我们整个这个代码是不是空间就就弹出去了。弹出去之后呢,这个是不是就露出来了,M1方法战争,M1方法战争在这儿啊。它露出来之后,M2这行代码结束之后,再往下1O。所以呢,这个呢,就在这块又输出一个什么呀,叫做1O的一个东西输出了。O,这行代码一输出之后,这个呢,其实就弹出了啊。那这个一旦弹出去之后呢,接下来我们再往下这个就露出来了,这个闷方法就是处于处于占停了,因为上面不弹完了嘛,都释放了,那这样的话,我们焖方法这块怎么着就就开始执行,那闷方法这块呢,哎,这行代码往下执行就是闷over。
24:00
那么闷over呢,其实在这呢,它就会输出啊,输出一个manover,那输出闷over之后呢,接下来我们是就相当于这个,哎,这个方法是不是也就弹走了。那么弹走之后,摆在大家面前的是这个站怎么着啊,就空了是不是啊,站如果空的话,我们程序就怎么着结束了啊程序结束了,所以说呢,它的一个呃,步骤是什么呢?它是怎么输出的呢。嗯。他是输出谁呀,输出哎呀这个颜色不太行啊。这个先输出。是吧,哎,然后紧接着走到这儿,走到这儿以后呢,哎,走到这儿。是不是这个。对吧,哎,这个之后走到这儿,走到这儿之后怎么办,这个就压进来了。是不是这个。对吧,哎,这个执行到这儿之后呢,你再调M3 M3是不是压进来在这啊。哎,所以这边是什么呀。这是四吧。
25:02
对不对,哎,这是不是五啊,是是100。对吧,五输出之后呢,这边是不是就六了。好,这个一旦输入这个就弹走了,弹走之后六这这这边是什么呀。这七吧。这个弹走之后这边什么呀。八吧,他弹走之后怎么着啊?这,这不是九吗。对不对,哎,有这样一个输出的过程啊,那么其实我刚才画的这个东西,其实就相当于我们整个城区的一个执行的一个内存结构啊,内存结构就是你要注意,注意的是什么呢?就是这里面的这个I。还有跟这个I,还有跟这个I,还有跟这个X是四个局部变量。谁的内存都不着空间变量内存。但是你这个还在,你这个内存空间释放完之后,这个就没了。啊,包括你这块也是一样的啊,三个I和X是四块不同的。
26:04
局部变量啊。三个I和一个。X这四个变量。都是。局部变量。啊,都是局部变量。注意啊,这块呢,我X等于100,把X扔进去,把X进去,把X传进去,实际上是把X给了这个I。那么我当时怎么讲的,我不知道大家还记不记得特类型A等于100,假如说特类型B等于A,我当时怎么说的?各位还记不记得我把A要是给了B是怎么说的?是说把100怎么着复制一份给谁?给B对吧。所以AB是两块不同的内存空间,这个理解吗?就这个原理,就是这个赋值原理,就在这儿写上这个赋值原理啊是什么?是将A变量中保存的100这个数字复制一份,传给谁?传给B变量。
27:18
这个大家要要要注意啊,要注意,所以A和B是两个不同的内存空间啊,所以A和B是两个不同的内存空间,是两个局部变量啊局部变量。知道这个啊,In a等于100,把A呢通过等号付给B的意思。它是两块内存空间啊,是把A里边保存的这个一百一百复制一份给谁给B。我们这块如果是印的X等于100,你把X传进去,把X传给了这个I,它道理是跟这个是一样的。道理跟这个是一样的,是把X保存这个100这个数字,怎么着复制一份传给了M1,那么M1这块呢,有一个变量ii,如果再调M2,你会把这个I传进去,实际上这个I传给这个I,实际上还是一个道理,就是你把这个I变量里面保存一个值啊,传给谁啊,复制一份传给谁啊,啊传给我们的M2啊,所以这是四块不同的内存空间,今天呢,我们呢。
28:19
呃,就说这么多各位啊,就是说现在呢,嗯,这个内存结构图,你好好的再去理解一下啊,再去理解一下,就是方法调用的时候,我们叫什么过程啊,压战是不是方法执行结束叫啥呀?哎,谈战啊有这么一个。有这么一个,嗯,东西在里边啊,就大家想一想,这个东西我觉得应该掌握什么,就是我们画这个内存结构图干什么。为什么要画内存图?更深层次的理解代码。对吧,在代码没有运行之前啊,就能猜测出结果,我觉得这个其实就是一个内存学,呃,画内存图的一个重要的一个关键的地方啊,会内存图啊,会内存图后期错的时候,后期调错的时候会有很大的帮助啊,所以我们要画这个内存图,各位啊,第二点要注意方法区存什么方法区存什么。
29:34
代码啊,另外占内存存什么。存什么呀,存的是方法的,方法执行时的内存空间以及局部变量是不是,哎局部变量都是在我们这个,哎方法占占内存里边存储啊,那还有一个就是啊,方法调用时叫什么?哎压战啊,分配空间,然后第五个就是方法结束时,我们叫谈战是不是哎叫释放空间啊,一个是分配空间,一个是哎释放空间啊。
30:17
一个是分配空间,一个是释放空间啊,你为了理解这个程序的一个执行过程,我觉得还是有必要去研究一下这个内存的一个变化啊,内存变化哎压站谈站这个站的特点啊,啊再说一下吧,站的特点是进后出,后进先出原则啊,站特点就是先进后出,或者叫后进先出原则。后进先出原则。行了,那么今天呢,咱们就讲这么多,各位啊,讲这么多,嗯,老师成员变量存在哪个空间,这个以后再看啊,今天不说啊,今天不说。啊,今天不说。如果调用不同类的方法也一样没问题啊。
31:02
跟调哪个类没关系,你比如说你通过这个类去这个方法去调用别的类的是吧?啊别的类的方法同样内存图是一样的,内存图上没有变化啊,没有变化,内存图上是没有变化的啊,我再强调一下。呃,刚才这个图是吧。嗯,这个图是不是。啊,截个图也行。截图啊。我这个图片可以留着啊,可以留着截个图。拖一下来结吧。嗯。
我来说两句