00:00
好,那么接下来的话呢,我们来看下一个问题啊,也是我们回过来呢,说的这个点啊,说一维数组的内存解析。那我们从这个代码这个层面呢,其实该要测的呢,也都差不多了,那我们为了能够更好的去理解数度这个结构啊,哎,我们来谈谈它的一个内存的结构啊,那么一提到这个内存结构的话呢,呃,我们可能首先要谈一个问题,说Java中的内存啊,它是怎么划分的是吧。诶,这个我们得先了解一下,这个清楚以后我们再来看一下数组是怎么使用Java的这个内存结构的。啊,就跟说呢,你现在说你你你的这个家具你要怎么摆放呀,你先看你住哪儿啊,我这是个一室一厅啊,我还是一个两室一厅三室一厅的呢,啊还是住在地下室呢。对吧,诶你住的这个环境不一样呢,你这个摆放你家具的方式啊,你这些行李的方放的方式肯定也不一样啊行,那这儿呢,是我们遇到的第一个问题啊,那么我们后边讲面向对象的时候呢,这个事儿还会给大家说,现在呢,是我们首次引入进来,毕竟你要讲内存结构了,肯定要引入了。
01:02
好,那看我们的课件,课件里边往下找,这呢一维数组内存分析。首先第一个问题,Java虚拟机的内存划分。说为了提高运行的效率啊,对这个空间啊,进行了不同区域的划分,诶每一片区域呢,它都存放特定的数据啊,也有特定数据的处理和管理的方式。这是我们整个注意啊,大家如果以后要学习Java虚拟机的话呢,这就是它的一个架构图。感觉上怎么样?还行,不太复杂吧。挺好看的啊,这个图呢是呃,这个是我讲GM这个课的时候呢,画的这个图哈。哎,这个图的话呢,其实就是这个图了。但后来呢,发现网上有好多这个图,一度呢,我都以为是我抄的别人的啊。嗯。后来可能是大家好像发的很多帖子都用的这个图了啊,诶这个呢,就我刚才看了这个图,这个图你要觉得哎还行是吧,哎,那你再看一个复杂一点的。这个图哎,是不是感觉就更酸爽一些是吧?哎,咱们这块呢,看这个呢,稍微有点复杂啊,刚开始学Java不要着急,咱们看一个简单的啊,而且呢,还看一个简单里边的一个中英文都有的是吧,就这个图啊。
02:12
这呢是我们Java虚拟的整个一个架构图,Java虚拟机啊,它最初接触的这个东西啊,就是自解码文件,前面这个呢,比如我们Java c这个指令。哎,编译完以后呢,生成自源码文件这块呢,跟Java虚拟机没关系啊。哎,有了自解码文件以后呢,它这一个叫类加载器子系统就把你物理磁盘这个class文件呢,就加载到内存了,这个事儿呢,咱们先不讲。啊,一会呢,我们讲到这个后边这个章节叫反射的时候呢,我们到时候呢,再说一下这个事儿啊好,那我现在呢,就把这个数据呢,是不是一个class文件,咱们目前说呢,就对应的是一个类了,呃,然后呢,这个类里边呢,咱们定义了这个数组了,我就把这个数据呢,就给你放到内存了,这个呢,就是我们所谓的内存区域,就这个粉色的。好,那我们来看一看,说Java虚拟机呢,它来帮我们去分配这个数组到内存当中,那么第一个问题说内存中有几个部分呀。
03:04
哎,典型的话,我们要说分五个部分。这五个部分呢,分别对应的啊叫程序计数器啊,虚拟基站,本地方法站啊堆,还有这个方法区这样的五个结构。那很显然呢,每个结构呢,它放的东西呢,都不太一样了,那都放的是什么呢?我在这个课件里边呢,简单的写了一下。那简单写了一下啊,这个虚拟站呢,这里边儿写的叭较详细的就是放我们每个方法中的这个局部变量啊,这个大家可能一看呢,有点懵,这个我就先简单一说啊,一会儿呢,我们只看数组这块啊,然后堆里边呢,就放我们这个存储的这个对象的,比如我们真正拗出来的这个数组的对象就放在堆里边了。方法区呢,就放在我们整个加载这个类的信息的啊,就先泛泛一说,以后我们都会展开来讲的本地方法站,这就涉及到咱们Java呢,最初的时候会掉很多的C的一些库,C的这些库呢,就会涉及到Java层面呢,叫native的方法,这叫本地方法,就调C的时候呢,用的是这个站啊。
04:03
OK,然后程序计数器呢,其实就记录我们要执行的下一个指定的一个地址了,这一说呢,肯定大家也比较懵哈,诶先呢,不用研究这么多,回过来简单我们这块说一下说Java中内存结构是怎么划分的,哎,首先第一个问题。说呢。我们将。哎,内存区域。哎,划分为。诶,五个部分。哎,分别呢,叫做。呃,咱们按照这个,呃,这个结构呢,比较简单到复杂这个顺序来吧,呃第一个呢,叫做程序计数器啊。啊,这个相对来说就简单一点啊,然后虚拟基站。本地方法站。啊,然后呢堆空间,哎,然后呢方法区。啊,其实里边细节展开的话呢,细节还是蛮多的啊,咱不用关注那么多,这是第一个问题,然后第二个问题呢,跟咱们现在讲这个数组相关的啊。与目前数组相关的这个内存结构就俩。
05:02
啊,一个呢,叫做虚拟驿站。哎,对,一个呢叫做对。那就这俩结构,所以呢,我们就只谈这俩结构,后边呢,我们讲到面向对象的时候呢,咱们再把后边这个事呢依次展开啊,那这个呢叫虚拟站,那这块呢,我们首先举个例子啊,这个比如说咱们刚才呢,定一个in特形的数组叫AR啊,后边new了一个in特型的数组,哎,这呢,我把这个元素呢,还写几个啊123好,就以这样的一个结构为例,这个虚拟站呢,我们说它这里边放什么呢?它就放我们的数组名。啊,画我们的数组名,所以这个虚拟站呢,我们说它呢,呃,就是我们标准上来讲呢,是用于存放啊,这个叫方法中声明的变量,这个变量呢,我们其实叫做局部变量啊。先不用管那么多,咱们就先叫变量也行,那咱们这个代码不都目前写在main方法里了吗?呃,就是存放我们这个main方法中生命的变量,比如说咱们上面这个AR。
06:03
OK啊啊,这呢是这个虚拟站它的一个作用,那对应呢。那堆呢,我们说呢,就是用于存放。哎,这个数组的这个实体,实体呢,里边就是集数组的所有的元素。在数组中的。哎,所有元素,而且呢,咱们。呃,元素啊,而且咱们上面还提到了,就是数组的元素呢,是不是在内存中依次解密排列的是吧,占的是一整块空间,那这个空间呢,现在就能说了,是不是堆空间。哎,对的,就放在这个堆里边。啊,这个呢,比如。哎,比如我们后边这个123啊,数组这样的三个元素。诶行,那这个事儿呢,我们就基本上啊,先去理解清楚了,哎,那么后续呢,我们讲面向对象的时候呢,再展开去对它进行讲解,哎,那么接下来我们就来看看啊,具体的举举代码的例子,我们看内存中到底是怎么放这些数据的。哎,那这个事儿呢,去解释的话,咱们就打开这个课件,课件呢第五章数组这呢有一个PPT啊把这个呢打开。
07:05
咱们呢,就在这块呢,来给大家去做这个讲解,那刚才也提到了,跟数组相关的就是栈和堆。但呢,用英文来表示呢,叫stack。在堆呢,叫hip。这个站的话呢,大家如果学习过数结构,是不是也听过这个词。对,这个跟我们讲的那个数据结构中站呢是一个概念啊,哎,它满足什么样特征呢,叫站呢。哼。对,只能有一端进和出是吧。对哈,就是这个,这就咱们闲聊的哈,就是站的特点呢,就是诶你过来一个东西呢,放在这儿,再来一个呢,是往这放。再来一个王这法。呃,那出去的话呢,是不是也只能从这一端出去是吧?哎这个它得这个得这是如果是123的话呢,三是不是先出是吧?哎,然后二,然后一,所以这种呢,站的特点呢,就叫做先进的。后厨去。哎,或者叫后进的呢,先出去是吧,哎,这叫占的特点,诶这呢是数据结构中的一个概念啊,然后呢,咱们这儿呢也叫占,诶因为它呢也满足这样的特征哈,这个咱们呃一点点到时候展开去说啊。
08:12
好,那么咱们来看看啊,这呢我举了两个例子,看看这两段代码在内存中是如何分配空间的。首先看第一段代码。来首先呢,这个代码你得先熟悉熟悉啊,诶我这呢定义这个in的形的一个一位数组,这个长度呢是四哈,然后呢,紧跟着呢,我通过角标呃,这个零和二呢去给先应两个位置上的元素呢,负了值了,这呢是一段操作。下一个我定了一个string性的数组,常度的是二,然后呢,给第二个元素注意啊。哎,复制为呢,叫周杰伦。然后紧跟着的话呢,你发现我。又扭了一个数组是吧?长度是三。那么问啊,这一段代码内存中长什么样?咱们下边呢,就来画一画这个内存结构,下来的话呢,大家自己也画一下啊。
09:03
好了,刚才我们提到了,说这个用到的是叫栈和堆了站里边呢,放的是我们may方法中声明的这个变呃,数组变量名。好,那这个呢,我就是在站里边放了一个main方法啊,后边我会讲啊,每个方法在调用的时候呢,其实这个方法都会入战。啊,那么这个方法呢,其实它会对应着一个框,这个框呢叫一个战针。我就这样一写,你就这样一听,咱们后边呢,再去讲方法的时候呢,再展开来详细说啊,就是一个基本结构就这个框啊,这个框里边放的是什么呢?就放你这个may里边声明的变量。实际上这块呢,要严格来讲,我应该先放一个谁。我先放这个二。你这个行参这块是不是也是个变量。对,其实应该放它是吧,但是只不过这个题呢,咱们也没用着它啊,所以我就把它给忽略掉了啊哎,那么一上来的话呢,我在这里边定义了一个叫A21是吧。
10:03
好,我就放个121了,咱们说了啊,这个方法里边定义的这个数组的名啊,变量名我们就放到站里边了,好谬出来的一个长度为四的一个数组,那数组的元素呢,我们说要放在堆里了,一看这块没负值,它是不是有默认值。对的,而且呢,在内存中应该是连续的空间,所以呢,我就应该整一个,比如插入一个表格,这个长度呢是四。这样的。哎,我呢,就把它诶放在这儿了。诶放在这还没完事儿啊,放在这儿以后呢,诶这内存空间是内存中是连续的这个一串空间了,然后这一块空间呢,我们对外暴露的话呢,只暴露他的首地日值。哎,这个首地值呢,通常我们是用16进制来表示的了,所以呢,应该是0X是吧,比如说12AB。啊,我就用这个呢地址来表示它的一个首地址了,行还没完事哈,诶整体来看的话,你应该是把这个new的东西呢,是不是复制给左边。
11:05
下一个问题,Are里边到底放的是什么?毕竟是个变量嘛。对,他就放这个首地址值。哎哎,就发我们这个手机地址。行了,他有这个手地址以后呢,其实就构成了一个指针。因为呢,我顺着这个地址,不就找到你堆空间中这个数组的首位置了吗?对吧,哎,就这样啊,其实这个意义上来讲,咱们一开始提到说Java呢,说呃有间状性,它的间壮性呢,是去除了C和C语言当中,C加加语言当中这个指针啊,因为C和C加当中啊,它真的可以说指一块空间,然后往后移几个位置,几个字节就是下个元素了,在咱们JA2里边呢,其实它就没有,哎这个像C当中呢,处理的那么细致的,咱说呢,通常讲叫去除了指针。它呢,对外暴露呢,就是一个虚拟的一个地址啊,注意这个地址的话呢,它不是说真正内存中的地址是多少,它是虚拟算出来。
12:01
虚拟机嘛,是吧,你可以理解成虚拟算出来一个地址,而且呢,它不对外暴露,你后边这个,你说我在哪呢,在哪呢,这个地址它不暴露,他只暴露这个手地址。因为我们可以通过角标的方式呢,去往后找偏移量是吧。好了,哎,那我们去找后边元素就行,哎,还没完事哈,那我们不是都有默认值吗。那对于我们in特型来讲,这不就是零嘛。好,那么第一行代码写完了。体会一下啊,哪方站哪方堆手地直一直完事啊好,那么接下来的话呢,我们通过这个哎,这个数组这个变量找角标零是不就找到这个位置了,把它这个值呢,从零改成十。哎,把他呢,给他干掉。哎,改成这个尺。好,真的就做了一个赋值,然后紧跟着的话呢,你再呃,通过这个AR,一找这个角标,二把它改成20。哎,这个我就放这儿了啊。这个呢,一定要小心一点,你看清楚是哪一个啊。
13:00
小二,应该是这个了。嗯,把它呢,给它干掉,改成20。行,那么我说呢,这三行代码就结束了。这个放到外边,其实应该是在里边的啊。嗯,OK,行,这个完了以后呢,接着我们再看下边,哎,我呢又声明了一个叫死string类型的一个数组,这个叫AR22啊,那我就在呃这个基础上呢,我们这边又诶声明了一个,这个我们叫AR2。好,然后呢,你右边呢,用了一个长度为二的死锥形的一个数组。那那这块同样的我们需要呢,插入一个表格,长度为二。哎,往这边拽一下啊。好,这呢,我就放在这儿。诶,那同样道理,它呢,也会对外暴露一个首地址值。那这呢,我们也去记录一下啊,比如叫0X叫aab。啊,行。哎,这个地址呢,就是它,然后接着的话呢,你把这个整个附给左边这个AR2了,所以A2这块呢,记录的就是我们数组在堆空间当中的首元素的这个地址值。
14:06
啊,叫a ABB。哎,那通过这个地址呢,我们就指向了啊,你堆空间当中的这样的一个数组啊,这个咱们稍微往下移一下吧。哎,提到这儿啊。行,那就指过来了,指过来还没完事啊,这个里边呢,我们认为呢,它其实存在,就算是这个叫闹了。哎,这是空的意思啊,那翻译成中文呢,就是空的意思。好,然后呢,接下来我们通过这个角标的方式呢,去做赋值。把这个这个位置是吧,改成叫周杰伦,注意哈,这块呢,稍微唠叨两句,这个周杰伦呢,其实它不是严格意义上呢,就直接放在这儿的啊。诶,我先写这啊,它严格上来讲呢,不是直接放在这儿的,呃,这个咱们后边呢,讲这个string的时候呢,我再详细的给大家去说,暂且的话呢,如果我们一下呢,讲的很复杂的话呢,大家就懵了哈。
15:02
哎,就跟说什么呀,咱们上小学一二年级的时候呢,诶老师如果说骄傲说最小的数是几呢。咱们一定老师先会说是零,其实老师心里边儿还挺难受的是吧。哎,等你上了五六年级了,他才告诉你,其实还有负数啊,最小数是几呢?没有最小的是负无穷的是吧,但是你一二年你不能上来教负无穷,孩子懵了是吧?所以这块我们先啊知道就这就先看着是在这儿,其实这个呃,周杰伦这个事儿的话呢,它挺复杂的,因为Java中这个字符串呢特别多,所以呢,他在设计的时候呢,就专门啊有一个区域呢,叫字符串常量池,专门来放字符串了啊后边我们就是把它真正的结构呢引出来先暂且呢,咱们就理解成就放这儿了啊。行,这个呢,我们就先这样放。然后啊,你看下一行代码,这个很关键了。这个AR呢,你看我又重新的去。出了一个值是吧。所以这里边儿有个小的技巧,就是凡是你看到new了。那就意味着你要重新开辟一块空间了。
16:02
啊,那这呢,就意味着我们又在堆空间当中,是不是,诶,开辟这一块连续三个区域的一个数组是吧。这块整仨。哎,这么着一下。对,然后呢,我们往这儿一放,这个稍微的有点挤了。这样啊。哎,这个放到这儿。那这个这样这样就解开啊,放开了啊好,这边一开始指向它,然后现在是指向它了,这个呢,既然你新旧了一个长度为三,它也会有一个所谓的手提值啊。给咱们这么着一下啊。这个地址呢,比如说那叫0X啊一二。0X啊12BA吧,B有点。CD吧,这样啊好,那么这个地址的话呢,注意现在我把这个地址呢,又要重新附给这个AR2了。那就意味着原有的这个地址呢,就不要了是吧。
17:02
把它干掉啊。诶,换成咱们现在这个新的地址。0X啊12CD。诶,换成这个地址了,好,那么有了这个地址以后呢,那就意味着我们当前这个AR呢,其实你就指向了新的这个数组了,那原来的这个地址就不存在了。称号的。这是吧,我就用它来表示了啊,把它给擦掉了。哎,这个我就哎不真实的把它给抹掉了,我就留着这个过程了啊行,这个呢,就不存在了,指向它,然后这里边的话呢,呃,它这个都是no。哎,这么着行,那么接着这个代码,如果下边去问说AR2角标一的这个位置,它的打印结果是多少?是不是应该是这个位置是闹了,哎,这个呢就不存在了。啊,注意那其实这里边儿呢,有一个什么点呢,就是说诶,我们在内存中,尤其是这个堆空间里边啊,如果发现这个区域呢,没有任何的指针指过来了。
18:07
那说明那就没有任何一个结构要调它了,是吧,既然没有任何结构要调用它了,那它就。没有用了是吧。啊,那既然没有用了,那它就是一个垃圾了,他要是个垃圾的话呢,呃,这个垃圾回收器呢,是不是就把它给回收掉了。啊,这个叫garbage collector叫垃圾回收器啊,诶就把它呢给回收掉了,哎就没有了是吧,然后呢,紧跟着我们这个main方法是不是就执行结束了。美方要执行结束呢,其实它整个这个框,我们叫一个战针,这个战针呢,就弹出战了。因为没有用了嘛,他就出战了,他一出战呢,就意味着占空间里边是不是这个跟这个就没有了。这俩要没有了,这俩指针是不是也没有了。然后呢,JC一看说,诶这两个结构呢,也没有任何的指针指过来了,这两个是不是也就跟着删了。哎,所以最后呢,就是内存空间中这些就全都没有了。诶,简单演示一下这个回收它的一个简单判定的一个事儿,好,那么这个代码呢,就是我们讲的这个基本的一个内存结构哈,诶这呢,我也可以把它呢CTRLC。
19:05
回过来方便呢,大家看咱们直接CTRLV啊,我就保存到这了,Shift加F6。改个名啊,EV数组的啊,内存解析一啊好,这是第一个图,然后这个你直接双击呢,这不就能看了啊好,接下来再回过来,我们再看下面这个题目啊。这个呢,稍微的啊,跟那个又不一样了啊,看看这个题目,这呢我们是印着一个呃数组呃长度为三,然后呢,分别给这个元素去赋值,打印这三个元素值,那这个看似来比较简单,好上来了我们就直接写啊嗯,这个数组变量呢,放在站里边叫AR2。然后呢,拗了一个长度为三的。长等于三的。哎,这么着啊,这样子。哎,往这一放。啊,这呢有一个手地日值。啊,这个我们去指明一下啊,0X,比如说啊12AB啊,还是拿它来说。
20:02
然后呢,把这个地址呢,我们就付给了你账空间里边存放的这个AR了。啊,12AB。行,那么通过这个地址值呢?我们占空间的AR指向对空间,因为呢,是int型的数组零。哎,这是默认初始化值,接下来通过显示赋值的方式,我们把这三个变量呢都,哎,这个零呢,都给它改掉了。分别呢,改成567。嗯,这样,嗯。行,那这个是六。7OK啊好,那么这样的话呢,我们这几行代码就搞定了。然后呢,我们去打印A201和二,那分别呢,就是567。诶没有问题,好,接着大家你看这块啊,这个呢,稍微的有点不一样了,我们呢,又重新的定义了一个变量叫A21。哎,怎么叫重新定义呢,你发现前面有类型。
21:01
只要建类型了,那说明就是一个新的变量啊,A1呢,我们是拿AR2去进行的赋值,这个操作什么意思。对啊,你看我这写的说将AR2的地址支付给了AR21。诶,这个一定要小心点啊,你说我们这定义一个新的变量啊,叫A2了,那是不是这个变量我们在对空间里边又重新造了一个数组呢。其实没有。嗯,这个我们再变小一点啊,这个呢,A21呢,哎,说你这拿A2去负的值,那是不是我们对空间里边就意味着这个结构呢,重新的也整了一份呢,没有。所以呢,再强调一下啊,包括刚才我们讲这个题目也说了,只要你出现new了。表示呢,我们在对空间里边呢,要新造一个数组,如果没有出现new,就不会新开辟空间。New就是心有一块地儿是吧?哎,那这块没有出现new就不会有这个结构了,好,那这块呢,我们到底存什么呢?那就看你这里边儿保存的什么,我们就传什么。
22:05
你存的是个地址值,那我呢就也传这个地址值,所以说我们A21的这个值呢,它也是0X12AB。哎,它也是这样一个值。好,它要也是这个值的话呢,那岂不是意味着我们这个AR1是不是也指向了它了。哎,事实情况确实如此,也指过来了,好,那么接下来的话呢,我们通过A21的方式呢,把角标一的位置改成九了。把它呢干掉。改成九。哎,就变成九了,行,那这个呢,我们要变成九以后,如果我们再去打印这个AR2啊,通过它去调这个角标一。是不是也是九。哎,这呢,就是我们这个内存的一个特点。哎,大家呢,熟悉熟悉啊,两道题目呢,各自都不一样啊。这个我们把它那也拿过来,放到我们这个下边啊,CTRLV。
23:02
啊,Shift加F6。看一数组。的按内存来解析二。这样就行了。好,那么刚才呢,咱们演示的这个事儿呢,你也可以在这块呢,我们把它复现一下啊,比如说啊,咱们看一看,其实就刚才这个代码呗。这个啊,我把这个代码呢,你看啊,我CTRL一下。我站到这儿啊,我CTRLV哟。这块我自己写一下吧,咱们这块写一下啊,这个呢,我叫A22啊,我叫A吧,上面我们都有A2了啊,我叫A1又一个in的型的数组,我就直接在这块呢,给它附上值了啊来123。行,这个大家脑海当中浮现出来,长什么样子?然后呢,我接着再去定一个数度,叫A2,拿A1负的值。啊,然后呢,我A2把这个角标一的这个元素呢,我改成十。相当于呢,我是把这个元素哈。
24:02
是不是改成十了?哎,对的啊,所以呢,我们再去打印一下这个A1的角标一。就是。十是吧,嗯,走起。你看这个十这不就出来了吗。哎,就这个特点啊,好,再接着来你看啊,我们这块呢,是不是做了一个赋值操作啊。这个复制完以后呢,你看我们在这个位置,我们去打印一下,这个叫A1。打印一下AR。他俩的是不是存的叫地址值啊。哎,这个值应该是一样的是吧。那就长这样啊。这个就是我们,你看这个艾呢,就是你在哪,这不就是我们说的16进制吗。是不是这个呢,它表示的比较长而已啊,然后前面这块呢,其实也表达出来我们当前这个元素的一个类型了啊。这一个中号呢,表示的就是一为数组了,I呢,就是你是in的类型的。哎,所以长这样,你要是大玻璃型的这个呢,就不是I了啊。对啊,呃,相应的这个特征大家就知道了,行,这个呢,就是我们说的这个内存结构,那么关于一维数组的这几个知识点呢,咱们就讲完了,最后关于内存这个事儿呢,稍微的有点难度啊,然后大家呢去理解理解,呃,能自己画呢就画一画,后边我们讲面向对象的时候呢,还会再去画内存结构的。
我来说两句