1. 程式人生 > >我不想成為鹹魚系列之字串建立方式及記憶體的簡單分析

我不想成為鹹魚系列之字串建立方式及記憶體的簡單分析

前言:今天不學習,明天變鹹魚

我們都知道建立字串的方式有兩種(基本的建立方式,clone序列化...不考慮)

a.String s1 = "asdf";

b.String s2 = new String("asdf");

我們首先分析下他在記憶體中的分配情況:

對於s1來說他會在"棧"記憶體中建立一個引用,之後去"程式碼區域"中的字串常量
池中去尋找看看存不存在S1這個引用,如果不存在那麼在"字串常量池"中會有一
個s1的物件,如果存在那麼直接將s1的引用指向字串常量池中即可
也就是說這樣:
    String s5 = "apple";
    String s6 = "apple";

    System.out.println(s5 == s6);
    System.out.println(s5.equals(s6));

true
true

這樣子就解釋了為什麼s1與s2不相等的原因
在我認為首先記憶體存放的位置就不一樣。一個在s1在常量池中,s2在堆中.所以不
相等.

程式執行時,物件是怎麼進行安置的呢?特別記憶體是內養分配的呢?

首先,你需要知道的是有五個不同的地方可以儲存資料
    - 1) 暫存器
    - 2) 堆疊
    - 3) 棧
    - 4) 常量儲存
    - 5) 非RAM儲存 

分析下我以前的知識儲備,如圖:

下面是結合書和資料進行了調整以及補充

    - 1) 暫存器:這是位於最快的儲存區域,因為它位於不同於其他儲存區的內部--->處理器內部.但是暫存器數量是極其有限的(如果你學過組合語言應該清楚寄存
        - 器大概有這些:
                     拿8086CPU來舉例:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PWS
                     其中AX,BX,CX,DX這四個暫存器通常用來存放一般性資料. 
        )跟CPU直接打交道的,速度非常快.按照他們的讀取速度可以分為以下幾類:

        1. 暫存器(Register)
        2. 快取(Cache)
        3. 內部儲存器(RAM)
        4. 外部儲存器(Hard Drive)

我們平時所說的記憶體就是第三類RAM(支援讀寫).

    - 2) 堆疊:位於通用RAM(隨機訪問儲存器中),但是可以通過堆疊指標從處理器那裡獲得直接支援(這裡面透露了一個資訊"棧",我們應該都知道"棧"他有兩種
             方式
                a.push() 入棧
                b.pop()出棧
             且遵循後進先出的原則
             )若堆疊指標向下即pop()入棧,標誌著要分配新的記憶體,相反,向上移動則意味著出棧,釋放記憶體.
             重點:在建立物件的時候,Java系統必須知道儲存在堆疊內所有項(我認為是分別配的地址的引用)的確切生命週期,以便於上下移動.一般情況下,僅
             僅是把物件的引用存放在堆疊中.
    - 3) 堆:一種通用的記憶體池(也位於RAM區:RAM Suppoted Read And Write),用於存放Java中所有實際的物件(記憶體),堆不同於堆疊的好處是:編輯器不
           不需要知道儲存的資料在堆裡面存活多長時間。很靈活,但是為了靈活必須付出一定的代價(開闢記憶體是十分耗費效能的,因為存在兩個問題
           1.不知道物件的宣告週期,需要呼叫JVM裡面的GC來搞定(但是有的時候並不能及時收回).
           2.耗費效能,如果你瞭解過GC的回收演算法,你就會知道會消耗時間去遍歷的
            ),

    - 4)常量儲存:
                下面有一段話
                執行時常量池(Runtime Constant Pool)是方法區(Method Area)的一部分,是各執行緒共享的記憶體區域。

    - 5)非RAM儲存:如果資料完全存活於程式之外,那麼它可以不受程式任何的控制,在程式沒有執行的時候也可以存在.
                  其中兩個基本的例子就是:"持久化物件"和"流"物件.暫時就寫到這裡面.我需要深度思考.回來繼續補充