自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java核心之Java內(nèi)存分配原理(二)

開(kāi)發(fā) 后端
本文介紹的是java內(nèi)存分配原理,分為兩篇為大家介紹,希望能夠?qū)δ阌袔椭黄饋?lái)看。

JAVA內(nèi)存分配與管理是Java的核心技術(shù)之一,之前我們?cè)榻B過(guò)Java的內(nèi)存管理與內(nèi)存泄露以及Java垃圾回收方面的知識(shí),今天我們?cè)俅紊钊隞ava核心,詳細(xì)介紹一下Java在內(nèi)存分配方面的知識(shí)。

String常量池問(wèn)題的幾個(gè)例子

下面是幾個(gè)常見(jiàn)例子的比較分析和理解:

  1. String a = "a1";   
  2. String b = "a" + 1;   
  3. System.out.println((a == b)); //result = true   
  4. String a = "atrue";   
  5. String b = "a" + "true";   
  6. System.out.println((a == b)); //result = true   
  7. String a = "a3.4";   
  8. String b = "a" + 3.4;   
  9. System.out.println((a == b)); //result = true  

分析:JVM對(duì)于字符串常量的"+"號(hào)連接,將程序編譯期,JVM就將常量字符串的"+"連接優(yōu)化為連接后的值,拿"a" + 1來(lái)說(shuō),經(jīng)編譯器優(yōu)化后在class中就已經(jīng)是a1。在編譯期其字符串常量的值就確定下來(lái),故上面程序最終的結(jié)果都為true。

  1. String a = "ab";   
  2. String bb = "b";   
  3. String b = "a" + bb;   
  4. System.out.println((a == b)); //result = false  

分析:JVM對(duì)于字符串引用,由于在字符串的"+"連接中,有字符串引用存在,而引用的值在程序編譯期是無(wú)法確定的,即"a" + bb無(wú)法被編譯器優(yōu)化,只有在程序運(yùn)行期來(lái)動(dòng)態(tài)分配并將連接后的新地址賦給b。所以上面程序的結(jié)果也就為false。

  1. String a = "ab";   
  2. final String bb = "b";   
  3. String b = "a" + bb;   
  4. System.out.println((a == b)); //result = true  

分析:和[3]中***不同的是bb字符串加了final修飾,對(duì)于final修飾的變量,它在編譯時(shí)被解析為常量值的一個(gè)本地拷貝存儲(chǔ)到自己的常量 池中或嵌入到它的字節(jié)碼流中。所以此時(shí)的"a" + bb和"a" + "b"效果是一樣的。故上面程序的結(jié)果為true。

  1. String a = "ab";   
  2. final String bb = getBB();   
  3. String b = "a" + bb;   
  4. System.out.println((a == b)); //result = false   
  5. private static String getBB() {   
  6. return "b";   
  7. }  

分析:JVM對(duì)于字符串引用bb,它的值在編譯期無(wú)法確定,只有在程序運(yùn)行期調(diào)用方法后,將方法的返回值和"a"來(lái)動(dòng)態(tài)連接并分配地址為b,故上面 程序的結(jié)果為false。

通過(guò)上面4個(gè)例子可以得出得知:

  1. String s = "a" + "b" + "c";  

就等價(jià)于

  1. String s = "abc";   
  2. String a = "a";   
  3. String b = "b";   
  4. String c = "c";   
  5. String s = a + b + c;  

這個(gè)就不一樣了,最終結(jié)果等于:

  1. StringBuffer temp = new StringBuffer();   
  2. temp.append(a).append(b).append(c);   
  3. String s = temp.toString();  

由上面的分析結(jié)果,可就不難推斷出String 采用連接運(yùn)算符(+)效率低下原因分析,形如這樣的代碼:

  1. public class Test {   
  2. public static void main(String args[]) {   
  3. String s = null;   
  4. for(int i = 0; i < 100; i++) {   
  5. s += "a";   
  6. }   
  7. }   
  8. }  

每做一次 + 就產(chǎn)生個(gè)StringBuilder對(duì)象,然后append后就扔掉。下次循環(huán)再到達(dá)時(shí)重新產(chǎn)生個(gè)StringBuilder對(duì)象,然后 append 字符串,如此循環(huán)直至結(jié)束。如果我們直接采用 StringBuilder 對(duì)象進(jìn)行 append 的話,我們可以節(jié)省 N - 1 次創(chuàng)建和銷(xiāo)毀對(duì)象的時(shí)間。所以對(duì)于在循環(huán)中要進(jìn)行字符串連接的應(yīng)用,一般都是用StringBuffer或StringBulider對(duì)象來(lái)進(jìn)行 append操作。

String對(duì)象的intern方法理解和分析:

  1. public class Test4 {   
  2. private static String a = "ab";   
  3. public static void main(String[] args){   
  4. String s1 = "a";   
  5. String s2 = "b";   
  6. String s = s1 + s2;   
  7. System.out.println(s == a);//false   
  8. System.out.println(s.intern() == a);//true   
  9. }   
  10. }  

這里用到JAVA里面是一個(gè)常量池的問(wèn)題。對(duì)于s1+s2操作,其實(shí)是在堆里面重新創(chuàng)建了一個(gè)新的對(duì)象,s保存的是這個(gè)新對(duì)象在堆空間的的內(nèi)容,所 以s與a的值是不相等的。而當(dāng)調(diào)用s.intern()方法,卻可以返回s在常量池中的地址值,因?yàn)閍的值存儲(chǔ)在常量池中,故s.intern和a的值相等。

總結(jié)

棧中用來(lái)存放一些原始數(shù)據(jù)類(lèi)型的局部變量數(shù)據(jù)和對(duì)象的引用(String,數(shù)組.對(duì)象等等)但不存放對(duì)象內(nèi)容堆中存放使用new關(guān)鍵字創(chuàng)建的對(duì)象.字符串是一個(gè)特殊包裝類(lèi),其引用是存放在棧里的,而對(duì)象內(nèi)容必須根據(jù)創(chuàng)建方式不同定(常量池和堆).有的是編譯期就已經(jīng)創(chuàng)建好,存放在字符串常 量池中,而有的是運(yùn)行時(shí)才被創(chuàng)建.使用new關(guān)鍵字,存放在堆中。

責(zé)任編輯:于鐵 來(lái)源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-07-11 18:02:50

java

2010-09-09 10:09:07

Java內(nèi)存分配

2010-09-25 14:38:18

Java內(nèi)存分配

2021-02-28 13:22:54

Java內(nèi)存代碼

2010-09-25 14:12:50

Java內(nèi)存分配

2010-09-17 16:14:22

Java內(nèi)存分配

2010-09-25 15:19:01

2020-11-04 15:35:13

Golang內(nèi)存程序員

2015-11-16 11:22:05

Java對(duì)象內(nèi)存分配

2009-06-03 15:52:34

堆內(nèi)存棧內(nèi)存Java內(nèi)存分配

2021-03-22 11:51:22

Java內(nèi)存棧上

2011-05-26 15:41:25

java虛擬機(jī)

2025-01-02 11:06:22

2017-03-08 10:06:11

Java技術(shù)點(diǎn)注解

2021-09-13 08:37:28

Java 語(yǔ)言 Java 基礎(chǔ)

2022-10-11 08:37:43

Servlet配置版本

2023-09-19 22:47:39

Java內(nèi)存

2016-09-26 17:09:28

Java并發(fā)編程內(nèi)存模型

2018-11-20 09:37:19

Java內(nèi)存模型

2021-09-10 15:16:19

Kubernetes核心組件運(yùn)維
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)