乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      關(guān)于java棧與堆深入了解 對一些錯誤認識的糾正

       風丨瀟瀟 2010-09-26
      1. 棧(stack)與堆(heap)都是Java用來在Ram中存放數(shù)據(jù)的地方。與C++不同,Java自動管理棧和堆,程序員不能直接地設置?;蚨?。
      //棧都是由運行環(huán)境來處理的,這點C++和java沒有什么不同.對于堆,不過java多了個GC.
      2.這里的堆和棧首先要明確是虛擬機棧,和寄存器根本不是一個級別的東西,就別比較了.
      3.棧數(shù)據(jù)共享好像是作者自己創(chuàng)造的概念.而且給基本類型也引入了"引用"的概念,不知道出于何種打算.
      java虛擬機規(guī)范中說:Primitive values do not share state with other primitive values. A variable whose type is a primitive type always holds a primitive value of that type.
      看一下實際的處理情況:
        int a=3;
        int b=3;
        int c=65535;
        int d=65535;
        int e=32330;
        int f=32330;
      看對應的虛擬機指令,可以知道變量里實際存儲的是什么:
      Code:
        0: iconst_3 //3
        1: istore_1
        2: iconst_3 //3
        3: istore_2
        4: ldc #2; //int 65535
        6: istore_3
        7: ldc #2; //int 65535
        9: istore 4
        11: sipush 32330
        14: istore 5
        16: sipush 32330
        19: istore 6
        21: return
      可以看出每個變量保存自己的值.(具體指令的意義參考java虛擬機規(guī)范)
      這里要注意的是對于int值,如果它大于short能表示的范圍,則放到常量池中去.
      11: sipush 32330
        14: istore 5
      這句,11-13,正好是3個字節(jié)的指令大小,一個字節(jié)是sipush指令,2個字節(jié)用來存儲32330這個數(shù).兩次使用到這個數(shù),都是把它直接存給變量的,所以原貼中一直強調(diào)的"棧中共享" 的說法明顯不對.
      對于65535,它是大于兩個字節(jié)的,編譯的時候把它放入常量池部分,而把取這個數(shù)的指令寫為ldc#2,我感覺這樣一個直觀的好處是減少了指令代碼的長度.尤其是多次使用到一個相同的數(shù)時.

        其實,java 對變量的處理很簡單,基本類型變量存放值,引用類型存放一個"引用" (實際就是一個"指針" ,以前曾經(jīng)和別人討論過,很多人認為是個"句柄",并舉了很多證據(jù),但是我后來看到了sun的java hotspot白皮書,里面直接說明了,引用實際就是一個c的"指針" ,使用句柄需要多次間接查找,會帶來效率的瓶頸,當然這個指針并不是直接指向?qū)嶋H的對象,實際指向的是一個兩個機器字大小的對象頭,對于數(shù)組是3個機器字大小的對象頭,因為還要保存數(shù)組的長度) .
      java設計時保留基本類型而不把一切都設計為對象,就是出于效率考慮,如果對于基本類型再通過"引用"去查找值,何苦呢?
      4.String也是包裝類? 這應該也是作者自己定義了包裝類的概念,去java語言規(guī)范里看看什么是wrapper class.
      5.Integer i = 3;編譯器如何處理?
      sun的編譯器是這樣處理的:
      Integer i=Integer.valueOf(3);
      而不是通過new來創(chuàng)建了,因為Integer類中靜態(tài)的創(chuàng)建了-128~+127之間的對象,需要的數(shù)在這個范圍之內(nèi)時,直接返回,此范圍之外的數(shù)才通過new來創(chuàng)建.
      簡單測試.
      Integer i=3;
      Integer j=3;
      我們測試i==j會發(fā)現(xiàn)它是true.
      String str = new String("abc");去看String類的構(gòu)造方法會發(fā)現(xiàn),這里用的是String(String original)來創(chuàng)建的,也就是說用一個String來創(chuàng)建一個String,"abc"編譯的時候編譯器會把它加入常量池部分.不知道原貼所謂的包裝類是如何得來的.
      csdn 的java版有個“推薦”的專門講String常量池的帖子,很不錯。
      5."JVM發(fā)現(xiàn)在棧中沒有存放該值的地址,便開辟了這個地址,并創(chuàng)建了一個新的對象,其字符串的值指向這個地址。 "又沒有分清編譯器和虛擬機的職責分配.編譯器會把"abc"放入常量池,并記住它在常量池中的位置,別的地方用到的時候編譯器直接生成ldc指令來制定了,不會讓jvm去找,去開辟地址等等.
      7.原貼明顯不知道常量池的存在,好像是把常量池的數(shù)據(jù)都認為是"棧"的了.
        java新增了StringBuilder來處理可變字符串,如果不需要多線程環(huán)境,應該首先選擇這個,而不是StringBuffer

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多