Java內存空間理解
堆:堆主要存放Java在運行過程中new出來的對象,凡是通過new生成的對象都存放在堆中,對於堆中的對象生命周期的管理由Java虛擬機的垃圾回收機制GC進行回收和統一管理。類的非靜態成員變量也放在堆區,其中基本數據類型是直接保存值,而復雜類型是保存指向對象的引用,非靜態成員變量在類的實例化時開辟空間並且初始化。所以你要知道類的幾個時機,加載-連接-初始化-實例化。
棧:棧主要存放在運行期間用到的一些局部變量(基本數據類型的變量)或者是指向其他對象的一些引用,因為方法執行時,被分配的內存就在棧中,所以當然存儲的局部變量就在棧中咯。當一段代碼或者一個方法調用完畢后,棧中為這段代碼所提供的基本數據類型或者對象的引用立即被釋放;
常量池:常量池是方法區的一部分內存。常量池在編譯期間就將一部分數據存放於該區域,包含基本數據類型如int、long等以final聲明的常量值,和String字符串、特別注意的是對於方法運行期位於棧中的局部變量String常量的值可以通過 String.intern()方法將該值置入到常量池中。
靜態域:位於方法區的一塊內存。存放類中以static聲明的靜態成員變量。
方法區:是各個線程共享的內存區域,它用於存儲class二進制文件,包含了虛擬機加載的類信息、常量、靜態變量、即時編譯后的代碼等數據。它有個名字叫做Non-Heap(非堆),目的是與Java堆區分開。
需要特別注意的是:
方法區是線程安全的。由於所有的線程都共享方法區,所以,方法區里的數據訪問必須被設計成線程安全的。例如,假如同時有兩個線程都企圖訪問方法區中的同一個類,而這個類還沒有被裝入JVM,那么只允許一個線程去裝載它,而其它線程必須等待 !
最后總結起來就是:
棧:為即時調用的方法開辟空間,存儲局部變量值(基本數據類型),局部變量引用。注意:局部變量必須手動初始化。
堆:存放引用類型的對象,即new出來的對象、數組值、類的非靜態成員變量值(基本數據類型)、非靜態成員變量引用。其中非靜態成員變量在實例化時開辟空間初始化值。更具體點,個人感覺非靜態成員變量是放在堆的對象中。
方法區:存放class二進制文件。包含類信息、靜態變量,常量池(String字符串和final修飾的常量值等),類的版本號等基本信息。因為是共享的區域,所以如果靜態成員變量的值或者常量值(String類型的值能夠非修改,具體請查看博客)被修改了直接就會反應到其它類的對象中。
文章轉載至:https://blog.csdn.net/terstdfhuc/article/details/86526047