Thinking in Java第二章就说了这个东东
看看这个,就不用说了:
Where storage lives
It’s useful to visualize some aspects of how things are laid out while the program is running—in particular how memory is arranged. There are six different places to store data: 
Registers. This is the fastest storage because it exists in a place different from that of other storage: inside the processor. However, the number of registers is severely limited, so registers are allocated by the compiler according to its needs. You don’t have direct control, nor do you see any evidence in your programs that registers even exist. The stack. This lives in the general random-access memory (RAM) area, but has direct support from the processor via its stack pointer. The stack pointer is moved down to create new memory and moved up to release that memory. This is an extremely fast and efficient way to allocate storage, second only to registers. The Java compiler must know, while it is creating the program, the exact size and lifetime of all the data that is stored on the stack, because it must generate the code to move the stack pointer up and down. This constraint places limits on the flexibility of your programs, so while some Java storage exists on the stack—in particular, object references—Java objects themselves are not placed on the stack. The heap. This is a general-purpose pool of memory (also in the RAM area) where all Java objects live. The nice thing about the heap is that, unlike the stack, the compiler doesn’t need to know how much storage it needs to allocate from the heap or how long that storage must stay on the heap. Thus, there’s a great deal of flexibility in using storage on the heap. Whenever you need to create an object, you simply write the code to create it by using new, and the storage is allocated on the heap when that code is executed. Of course there’s a price you pay for this flexibility. It takes more time to allocate heap storage than it does to allocate stack storage (if you even could create objects on the stack in Java, as you can in C++).Static storage. “Static” is used here in the sense of “in a fixed location” (although it’s also in RAM). Static storage contains data that is available for the entire time a program is running. You can use the static keyword to specify that a particular element of an object is static, but Java objects themselves are never placed in static storage. Constant storage. Constant values are often placed directly in the program code, which is safe since they can never change. Sometimes constants are cordoned off by themselves so that they can be optionally placed in read-only memory (ROM), in embedded systems.Non-RAM storage. If data lives completely outside a program, it can exist while the program is not running, outside the control of the program. The two primary examples of this are streamed objects, in which objects are turned into streams of bytes, generally to be sent to another machine, and persistent objects, in which the objects are placed on disk so they will hold their state even when the program is terminated. The trick with these types of storage is turning the objects into something that can exist on the other medium, and yet can be resurrected into a regular RAM-based object when necessary. Java provides support for lightweight persistence, and future versions of Java might provide more complete solutions for persistence.

解决方案 »

  1.   

    给一段侯捷先生的译文:
    Chapter 2: Everything is an Object 103
    儲存在哪裡
    程式執行時究竟如何放置物件?其記憶體佈局方式如何?如果能夠了解這
    ㆒點,會帶來很大幫助。有六個㆞方可以存放資料:
    1. 暫存器(Registers)。這是速度最快的儲存場所,因為暫存器位於
    處理器內部,這㆒點和其他種類的儲存媒介都不㆒樣。不過,由於
    暫存器個數有限,所以編譯器會根據本身需求適當㆞配置暫存器來
    使用。作為㆒個程式員,你不僅無法直接碰觸暫存器,也沒辦法在
    程式裡頭感覺到暫存器的任何存在跡象。
    2. Stack(堆疊),位於㆒般的RAM(random-access memory,隨
    機存取記憶體)㆗。處理器經由其指標(stack pointer)提供直接支
    援。當程式配置㆒塊新的記憶體時,stack 指標便往後移;釋放記憶
    104 Thinking in Java www.BruceEckel.com
    體時,指標則往前移回。這種方式不僅很快,效率也高,速度僅次
    於暫存器。由於Java 編譯器有責任產生「將stack 指標前後移動」
    的程式碼,所以它必須能夠完全掌握它所編譯的程式㆗「存在stack
    裡頭的所有資料的實際大小和存活時間」。如此㆒來便會限制程式
    的彈性。由於這個限制,儘管我們可以將物件的reference 儲存於
    stack 內,但卻不能將㆒般的Java 物件也置於其㆖。
    3. Heap(堆積)。Heap 是㆒種通用性質的記憶體儲存空間(也存在
    於RAM ㆗),用來置放所有Java 物件。Heap 勝過stack 之處在
    於,編譯器不需知道究竟得從heap ㆗配置多少空間,也不需知道從
    heap ㆖配置的空間究竟需要存在多久。因此,自heap 配置儲存空
    間可以獲得高度的彈性。每當你需要產生物件,只需在程式碼㆗使
    用new,那麼當它執行的時候,便會自heap 配置空間。當然,你
    得為這樣的彈性付出代價:從heap 配置空間,比從stack 配置(假
    設你真的可以在Java ㆗像C++㆒樣㆞自stack 產生物件的話),所
    耗費的時間多了不少。
    4. 靜態儲存空間(Static storage)。這裡使用「靜態」㆒詞,指的
    是「在固定位置㆖」(也在RAM 裡頭)。靜態儲存空間存放著「程
    式執行期間」㆒直存在的資料。你可以使用關鍵字static,將某個
    物件內的特定成員設為靜態,但Java 物件本身絕無可能置於靜態儲
    存空間㆗。
    5. 常數儲存空間(Constant storage)。常數值常常會被直接置於程
    式碼裡頭。因為常數是不會改變的,所以也是安全的。有時候常數
    會和外界隔離開來, 所以也可以放到唯讀記憶體( read-only
    memory,ROM)㆗。
    6. Non-RAM 儲存空間。如果資料完全存活於程式之外,那麼即使程
    式不執行,資料也能夠繼續存在,脫離程式的控制。streamed
    objects(串流化物件)和persistent objects(永續性物件)便是主
    要的兩個例子。在streamed objects 形式㆗,物件被轉換為㆒連串
    的bytes。這些bytes 通常用來傳送到另㆒部機器。在persistent
    objects 的形式㆗,物件被儲存於磁碟,所以即使程式結束了,這些
    物件的狀態還能夠繼續保有。此類儲存空間的特點在於,它們能夠
    將物件轉換為可儲存於其他媒介的形式,並在必要的時候將所儲存
    的資料還原成可儲存於RAM ㆗的㆒般物件。Java 提供了所謂「輕
    量級永續性(lightweight persistence)」,新版本有可能提供更完
    善的解決方案。