00:00
那讲完了这个string的基本特征之后啊,咱们下边来看第二个内容啊,叫做string的一个内存分配,这呢主要讲的就是string呢,在内存结构当中主要放在哪,那实际上呢,这个问题在咱们前面讲对空间讲方法区的时候啊,其实已经讲过了。对吧,已经讲过了,那这呢,咱们出一个完整性的考虑啊,把这个问题呢,咱们再谈一下啊,以及呢,咱们通过例子呢来证明一下啊,确实呢,是放在这样的结构当中了。啊,是这样行,那首先呢,我们来看这样一段文字,啊说呢,在Java语言当中有八种基本数据类型和一种比较特殊的类型,叫做string,啊这呢一共算是九种,那这九种从哪个维度上来看,它们可以放在一起呢?这呢我们就提到了一个说提供了一个常量池的概念。那咱们知道八种积分数据类型,在咱们平时的开发当中用的实际上也是非常频繁的,这跟string一样对吧?那既然使用非常频繁,我们就想考虑怎么能够让这个程序呢,执行的速度更快一些,那前提呢,就是说,诶先给你提供好是吧,别人要用跟你一样的话呢,我们就给你提供一个常量值,你就直接服用就完了,哎,那这时候呢,效率肯定就更快。
01:06
哎,这就我们提到这个常量池的一个,呃,这样的一个想法的一个缘由,包括呢,我们后续呢,是不是还有这个叫数据库连接池,呃线程池,虽然说呢,这个池子的好处这个不太一致吧,但是呢,呃,提供一个池子的一个,呃前提的想法都是一样的,就是我给你提供一些线程的啊,你就能够直接去用是吧,使得我们这个程序呢,诶执行效率更高。行,那么常量池呢,就类似于Java系统级别提供的一个缓存,对于八种基本数据类型来讲呢,都是系统呢来进行协调的,这个呢咱们就不用多去研究了,那么我们这呢,主要来看呢,就是关于这个string,那string的话呢,它的常量池的使用呢,主要有两种形式,一种呢,就是我们直接通过自变量的方式进行的一个声明,这个呢,就是直接在常量池当中分配的一个数据,那如果说字符串常量池里边已经有这个艾特硅谷点com了,那我们直接就复用,那接着呢再体现我们前面讲的叫不可变性是吧,你要修改的话,你重新造一个,不要影响人家别人用的那个at硅谷条com,对吧?行,嗯,那还有一种方式呢,就是我们,诶,不管你是通过什么样的方式吧,哎,拼接也好,这个new也好,还是直接量生命也好,总之呢,我们呢,呃,要想在常量池希望它显示的帮我们去放一个呃自由差常量,那这时候我们还可以去调用一个方法叫做int方法。
02:20
这个音的方法在某后边这个某一节当中,我们重点来谈这个方法,行先知道呢,有这样的两种形式,OK,行,那下边这个呢,对于大家来说就不太陌生了,咱们前面呢讲过。对吧,前面我们讲过啊,说呢,在JK6的时候呢,自12常量池是放在云纽带中的,那在七的时候呢,我们就对这个自二常量池呢,做了一个变化,把它呢放在了我们的对空间中,然后八的时候呢,我们没有永久带了啊,改成了教学空间,但是这时候呢,字符串常量池呢,还是在我们的对空间当中,没有移回来,哎,这个注意行,那那所有的磁物串呢,都保存在堆当中,呃,和其他的普通对象一样,这样呢,你在进行调约的时候呢,仅需要呢调整这个堆的大小就可以了,你说我们这个空间不足,那我这个不管你是自物串啊,用的比较多,空间不足了,还是说呢,我们这空间中你用的对象多了,我们直接呢去调整这个堆空间的大小就可以了。
03:12
啊,那原来的时候呢,我们放在的是这个永久带,大家知道这个永久带的默认的大小呢,实际上是比较小的啊,就pro size是比较小的,那比较小的话呢,我们这时候呢,是不是都不敢去用这个,呃,大量的去造这个词string了,是吧?那这时候很有可能会出现我们一个叫英语带的一个溢出了。那那这时候我们放到堆的时候呢,就相对来说就好一些,堆空间的话呢,一般我们设置的都相对来说是大一些。啊大一些,那这时候呢,我们就可以放开了,考虑去使用这个叫诶string.in Internet的方法,在这个Z叉常量池里边帮我们诶去动态的去创建一个这个string的一个Z叉常量。对吧,哎,就这样一个情况啊行,那这呢,就我们前面呢,讲方法区的时候呢,也提到过这个事儿,这呢是JDK6的概念概念,然后呢,这是JDK7的这个概念。然后下边呢是呃GT8我就没放了哈八呢是呃方法区的这个概念呢,做了一个调整,对于我们这个做二常量池来讲,还是在堆里边了啊,就没有放了,行,那为什么这个string table呢,要做一个调整,从这个用纽带呢,调整到这个堆里边呢,咱们前面讲方法去变化的时候呢,已经说过这个事儿了。
04:16
这是官网的一个说明是吧,嗯,大家再回忆一下我们当时怎么讲的。是吧,哎,为什么我们要去把这个string做一个调整呢?哎,我这写一下吧。嗯,其实刚才呢,我们也谈到一个原因,就是一开始的时候,你放到这个游泳袋,咱们这个游泳袋呢叫诶PM是吧,它这个prom size的话呢,默认情况下呢,比较小,那波人比较小的话呢,那我们要是放大量的这个字误串啊,实际上呢,就有可能导致我们这个永久带呢报这个OM了。那所以呢,我们诶就是诶还不太敢放,包括呢,这个int方法呢,也不太敢去调用是吧?哎,这是其一,那你要是咱们说你要是不去调离int方法,也不去直接通过这个自变量的方式,我们通过new的方式的时候呢,那你这时候呢,New的对象都是在对空间中的,对吧,咱们说过啊。
05:05
行,这是我们说的第一个问题,那么第二个问题的话呢,就是说呃,我们这个在永久带,即使呢,你把它这个空间呢,设置的是稍微大一些,我们呢去放这个自渣常量池中的这个常量,但是的话呢,我们知道这个永久袋呢,它是不是垃圾回收的频率很低啊。永久带。哎,回收哎频率低。这个永久贷的话呢,你想它叫永久贷啊,虽然说我们说这里边,呃,不一定真的是永久存在吧,但至少说我们是存在这个有的垃圾回收,呃,这个有的,这个Java虚拟机是没有,呃,设置这个永久带的垃圾回收的,咱们Java虚拟机规范里边,当时咱们不也看那一个官方规范说了,没有要求所有的Java虚拟机都去回收方法区是吧?啊,有的没有啊,当然这个houseport虚拟咱们是可以考虑去回收的,当然回收的频率呢,是极低,咱们基本上是不动这个永久带的。那这样呢,实际上实际上就意味着我们这个在呃永久带当中,如果你有一些不用的这个string字串的话呢,这个就不能够及时的进行回收了,那加上你空间也比较小,那是不是就比较容易的会报这个OM是吧。
06:15
当然呢,你报OM之前呢,我们进行for这C的时候呢,它当时也能够把你这个相应的一些垃圾呢给清理掉,但是这呢,毕竟这个频率比较低啊,毕竟频率比较低,所以这块呢,我们就啊基于这样的原因呢,就做一个调整,OK啊,这个大家理解这个事儿就行啊,那咱们这块呢,通过一个例子呢,给大家来证明一下啊,这呢看这个情况。看这个情况,我这呢是造了一个set,这个set里边呢,嗯,这个我去放这个字串,嗯,这个我往里边去放,我这呢是一个I,呃,就是string.value of I加加I加加这个呢,我们得到的是嗯,具体一个数值加上个引号这样的一个字符串,然后这个字符串呢,注意我掉了in方法,咱们就相当于提前来说一下这个int啊,当我们去调离int方法的时候呢,我们就一定会在字符串常量池里边帮我们生成对应的你那个字符串。
07:05
这不刚才说了是吧,怎么用这个常量池,其中呢,就涉及到这音的方法,咱们提前呢先用一下。或者大家在开发中实际上也都用过是吧,这是咱们就是做一个提前使用啊,那么这样的方式的话呢,我们就不断的去在自杀常量池里边去创建啊,零开始啊,零一二三四一直往上加,哎这呢我非常自信的是在少的范围之内呢,我们就能够让这个异常呢报出来,当然前提呢是我们设置了一下这个永久带,或者是叫对空间。好,那么在JK6的时候呢,我们还有永久带,我这呢这样来设置堆空间,还有这个永久带呢,我们都设置成是这个六兆的大小,好CTRLC一下,现在把咱们当前的这个13这块呢,我改成是JDK6。可以了,然后在这个run这块我们去修改。把这块呢改成16。嗯,注意咱们先啊13是吧六,哎这块呢,咱们看的是这个。这个程序啊,然后CTRLV一下没问题,这个参数呢,咱们前面都已经讲过了,大家应该都不陌生,好这块我们做一个执行。
08:11
出来了,那么这个时候啊,咱们的这个字符串在JD6当中,是不是存储在我们这个英语带当中的,所以这里边你看就报了叫pro space。哎,就报我们这个pro space这样的一个异常信息,哎很好理解是吧,然后呢,我们在这接着呢,在这个JD个八当中,我们去说明JD8呢,因为我们已经没有这个叫英语带了,所以这呢,我们需要替换成叫麦达space size和这个叫max麦达space这个size啊CTRLC一下。嗯,首先呢,我们在这修改,改成是这个八。然后回过来看这个位置,我们改成是这个八。把这个参数呢,整个给它换掉啊,CTRLV还是我们这个程序。来执行一下。
09:00
哎,出来了是吧,那这时候呢,报的是OM,然后呢叫Java hi space,注意我们现在呢,是不断的去在字符串常量池里边去提供这个字符串常量,然后呢,这时候是把我们这个堆空间给溢出了,那显然呢是因为我们这个string是不是就放在堆里了,哎,那我们相当于就证明了咱们前面说的这个在八里边啊,这个字符串常量还是放在这个堆空间中的。啊,就这样一个事实啊,行,这个呢,在面试当中呢,大家是可以去提的啊,不管你是从这个string的角度去提,还是从这个堆和方法区的一个变化的角度去提,面试当中我们也看过了几个大厂都会问八种一些这个内存结构上的一些变化啊,大家呢,要把这个事呢提出来啊,因为我们这里边确实呢,是不是验证了一下啊。OK啊,这咱们就说到这儿。
我来说两句