當前位置:首頁 » 存儲配置 » java存儲區

java存儲區

發布時間: 2022-06-12 18:51:04

java內存模型和Java內存區域的區別和聯系

內存模型就是各個區域的職責劃分,說起來是一個事情。
Java虛擬機在執行Java程序的過程中會把它所管理的內存劃分為若干個不同的數據區.這些區域有各自的用途,以及創建和銷毀時間,有的區域隨著虛擬機進程的啟動而存在,有的依賴用戶線程的啟動和結束而建立和銷毀,概括來說Java虛擬機包括以下幾個運行時數據區域,程序計數器,Java虛擬機棧,本地方法棧,Java堆,方法區,運行時常量池,(直接內存)

㈡ Java的堆內存是什麼

Java堆(Java Heap)是java虛擬機所管理的內存中最大的一塊
java堆被所有線程共享的一塊內存區域
虛擬機啟動時創建java堆
java堆的唯一目的就是存放對象實例。
java堆是垃圾收集器管理的主要區域。
從內存回收的角度來看, 由於現在收集器基本都採用分代收集演算法, 所以Java堆可以細分為:新生代(Young)和老年代(Old)。 新生代又被劃分為三個區域Eden、From Survivor, To Survivor等。無論怎麼劃分,最終存儲的都是實例對象, 進一步劃分的目的是為了更好的回收內存, 或者更快的分配內存。
java堆的大小是可擴展的, 通過-Xmx和-Xms控制。
如果堆內存不夠分配實例對象, 並且對也無法在擴展時, 將會拋出outOfMemoryError異常。

㈢ 主內存與java內存區域(堆,方法區)有什麼區別

這兩天看了一下深入淺出JVM這本書,推薦給高級的java程序員去看,對你了解JAVA的底層和運行機制有
比較大的幫助。
廢話不想講了.入主題:
先了解具體的概念:
JAVA的JVM的內存可分為3個區:堆(heap)、棧(stack)和方法區(method)
堆區:
1.存儲的全部是對象,每個對象都包含一個與之對應的class的信息。(class的目的是得到操作指令)
2.jvm只有一個堆區(heap)被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身
棧區:
1.每個線程包含一個棧區,棧中只保存基礎數據類型的對象和自定義對象的引用(不是對象),對象都存放在堆區中
2.每個棧中的數據(原始類型和對象引用)都是私有的,其他棧不能訪問
3.棧分為3個部分:基本類型變數區、執行環境上下文、操作指令區(存放操作指令)。
方法區:
1.又叫靜態區,跟堆一樣,被所有的線程共享。方法區包含所有的class和static變數。
2.方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變數。
為了更清楚地搞明白發生在運行時數據區里的黑幕,我們來准備2個小道具(2個非常簡單的小程序)。
AppMain.java
public class AppMain
//運行時, jvm 把appmain的信息都放入方法區
{
public static void main(String[] args) //main 方法本身放入方法區。
{
Sample test1 = new Sample( " 測試1 " ); //test1是引用,所以放到棧區里, Sample是自定義對象應該放到堆裡面
Sample test2 = new Sample( " 測試2 " );
test1.printName();
test2.printName();
}
}
Sample.java
public class Sample //運行時, jvm 把appmain的信息都放入方法區
{
/** 範例名稱 */
private name; //new Sample實例後, name 引用放入棧區里, name 對象放入堆里
/** 構造方法 */
public Sample(String name)
{
this .name = name;
}
/** 輸出 */
public void printName() //print方法本身放入 方法區里。
{
System.out.println(name);
}
}
OK,讓我們開始行動吧,出發指令就是:「java AppMain」,包包里帶好我們的行動向導圖,Let』s GO!

系統收到了我們發出的指令,啟動了一個Java虛擬機進程,這個進程首先從classpath中找到AppMain.class文件,讀取這個文件中的二進制數據,然後把Appmain類的類信息存放到運行時數據區的方法區中。這一過程稱為AppMain類的載入過程。
接著,Java虛擬機定位到方法區中AppMain類的Main()方法的位元組碼,開始執行它的指令。這個main()方法的第一條語句就是:
Sample test1=new Sample("測試1");
語句很簡單啦,就是讓java虛擬機創建一個Sample實例,並且呢,使引用變數test1引用這個實例。貌似小case一樁哦,就讓我們來跟蹤一下Java虛擬機,看看它究竟是怎麼來執行這個任務的:
1、 Java虛擬機一看,不就是建立一個Sample實例嗎,簡單,於是就直奔方法區而去,先找到Sample類的類型信息再說。結果呢,嘿嘿,沒找到@@,這會兒的方法區里還沒有Sample類呢。可Java虛擬機也不是一根筋的笨蛋,於是,它發揚「自己動手,豐衣足食」的作風,立馬載入了Sample類,把Sample類的類型信息存放在方法區里。
2、 好啦,資料找到了,下面就開始幹活啦。Java虛擬機做的第一件事情就是在堆區中為一個新的Sample實例分配內存, 這個Sample實例持有著指向方法區的Sample類的類型信息的引用。這里所說的引用,實際上指的是Sample類的類型信息在方法區中的內存地址,其實,就是有點類似於c語言里的指針啦~~,而這個地址呢,就存放了在Sample實例的數據區里。
3、 在JAVA虛擬機進程中,每個線程都會擁有一個方法調用棧,用來跟蹤線程運行中一系列的方法調用過程,棧中的每一個元素就被稱為棧幀,每當線程調用一個方法的時候就會向方法棧壓入一個新幀。這里的幀用來存儲方法的參數、局部變數和運算過程中的臨時數據。OK,原理講完了,就讓我們來繼續我們的跟蹤行動!位於「=」前的Test1是一個在main()方法中定義的變數,可見,它是一個局部變數,因此,它被會添加到了執行main()方法的主線程的JAVA方法調用棧中。而「=」將把這個test1變數指向堆區中的Sample實例,也就是說,它持有指向Sample實例的引用。
OK,到這里為止呢,JAVA虛擬機就完成了這個簡單語句的執行任務。參考我們的行動向導圖,我們終於初步摸清了JAVA虛擬機的一點點底細了,COOL!
接下來,JAVA虛擬機將繼續執行後續指令,在堆區里繼續創建另一個Sample實例,然後依次執行它們的printName()方法。當JAVA虛擬機執行test1.printName()方法時,JAVA虛擬機根據局部變數test1持有的引用,定位到堆區中的Sample實例,再根據Sample實例持有的引用,定位到方法去中Sample類的類型信息,從而獲得printName()方法的位元組碼,接著執行printName()方法包含的指令。

㈣ java代碼運行的時候將內存分成哪些區

您好,提問者:
java中在內存中劃分:棧內存和堆內存。
1、棧內存:棧中是存放一些定義的變數的引用,比如:int a = 1; a那麼就存在棧內存中,java中垃圾回收是JVM幫我們完成的,這里比C大大提高了程序員的繁碎。如果想要控制可以使用System.gc();來通知JVM虛擬機執行,但是什麼時候執行還是由JVM虛擬機來完成的。
2、堆內存:堆中是存放一些比如數組,map類型等。

㈤ java內存空間的分配問題

字元串不是放在棧裡面的,也不是放在堆裡面的,原因很簡單,String類的定義是static
final
的(值不能改變),也就是說所有被static
final
修飾的變數還有程序代碼都是被存放在代碼區的。
Person
p=new
Person();這句其實有三步,第一步要在棧空間分配空間存放p(這裡面存的是new出來的Person這個實例的地址),第二步在堆空間分配空間存儲new出來的Person,第三步才是p指向在堆中new出來的Person.

㈥ java中的全局變數存儲在堆上,還是存儲靜態區

帶static就是在靜態存儲區,反之不是
當我們實例化一個類的時候,首先會創建靜態的屬性於靜態存儲區,
之後會創建類所屬的屬性,就是你說的全局變數於棧中,
如果屬性為8種基本數據類型,則棧中存放值,
反之,棧中存放指向堆內存的地址

建議閱讀--<<thinging in java>>

㈦ Java內存中的棧,堆和方法區的用法有什麼不同

JAVA的JVM的內存可分為3個區:堆(heap)、棧(stack)和方法區(method)也叫靜態存儲區。

堆區:

  1. 存儲的全部是對象,每個對象都包含一個與之對應的class的信息。(class的目的是得到操作指令)

2.jvm只有一個堆區(heap)被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身

棧區:

  1. 每個線程包含一個棧區,棧中只保存基礎數據類型的對象和自定義對象的引用(不是對象),對象都存放在堆區中

2.每個棧中的數據(原始類型和對象引用)都是私有的,其他棧不能訪問。

3.棧分為3個部分:基本類型變數區、執行環境上下文、操作指令區(存放操作指令)。

方法區:

  1. 又叫靜態區,跟堆一樣,被所有的線程共享。方法區包含所有的class和static變數。

2.方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變數。

㈧ java語言中,類的成員變數分配在哪個內存區

成員變數有靜態和非靜態,靜態成員變數是共享數據,在共享區中,也叫方法區中。
非靜態成員變數在堆內存中,作用於整個類中。
而局部變數在棧內存中,定義在函數中,函數結束內存釋放。

㈨ Java中內存分為幾塊

你說的是jvm的內存空間吧。
在方法(代碼塊)中定義一個變數時,java就在棧中為這個變數分配JVM內存空間,當超過變數的作用域後,java會自動釋放掉為該變數所分配的JVM內存空間;而在堆中分配的JVM內存由java虛擬機的自動垃圾回收器來管理。

JVM內存區域組成

JVM內存分四種:

1、棧區(stacksegment)—由編譯器自動分配釋放,存放函數的參數值,局部變數的值等,具體方法執行結束之後,系統自動釋放JVM內存資源

2、堆區(heapsegment)—一般由程序員分配釋放,存放由new創建的對象和數組,jvm不定時查看這個對象,如果沒有引用指向這個對象就回收

3、靜態區(datasegment)—存放全局變數,靜態變數和字元串常量,不釋放

4、代碼區(codesegment)—存放程序中方法的二進制代碼,而且是多個對象共享一個代碼空間區域

在方法(代碼塊)中定義一個變數時,java就在棧中為這個變數分配JVM內存空間,當超過變數的作用域後,java會自動釋放掉為該變數所分配的JVM內存空間;在堆中分配的JVM內存由java虛擬機的自動垃圾回收器來管理,堆的優勢是可以動態分配JVM內存大小,生存期也不必事先告訴編譯器,因為它是在運行時動態分配JVM內存的。缺點就是要在運行時動態分配JVM內存,存取速度較慢;棧的優勢是存取速度比堆要快,缺點是存在棧中的數據大小與生存期必須是確定的無靈活性。

◆java堆由Perm區和Heap區組成,Heap區則由Old區和New區組成,而New區又分為Eden區,From區,To區,Heap={Old+NEW={Eden,From,To}},見圖1所示。

Heap區分兩大塊,一塊是NEWGeneration,另一塊是OldGeneration.在NewGeneration中,有一個叫Eden的空間,主要是用來存放新生的對象,還有兩個SurvivorSpaces(from,to),它們用來存放每次垃圾回收後存活下來的對象。在OldGeneration中,主要存放應用程序中生命周期長的JVM內存對象,還有個PermanentGeneration,主要用來放JVM自己的反射對象,比如類對象和方法對象等。

在NewGeneration塊中,垃圾回收一般用Copying的演算法,速度快。每次GC的時候,存活下來的對象首先由Eden拷貝到某個SurvivorSpace,當SurvivorSpace空間滿了後,剩下的live對象就被直接拷貝到OldGeneration中去。因此,每次GC後,EdenJVM內存塊會被清空。在OldGeneration塊中,垃圾回收一般用mark-compact的演算法,速度慢些,但減少JVM內存要求.

垃圾回收分多級,0級為全部(Full)的垃圾回收,會回收OLD段中的垃圾;1級或以上為部分垃圾回收,只會回收NEW中的垃圾,JVM內存溢出通常發生於OLD段或Perm段垃圾回收後,仍然無JVM內存空間容納新的Java對象的情況。

JVM調用GC的頻度還是很高的,主要兩種情況下進行垃圾回收:當應用程序線程空閑;另一個是JVM內存堆不足時,會不斷調用GC,若連續回收都解決不了JVM內存堆不足的問題時,就會報outofmemory錯誤。因為這個異常根據系統運行環境決定,所以無法預期它何時出現。

根據GC的機制,程序的運行會引起系統運行環境的變化,增加GC的觸發機會。為了避免這些問題,程序的設計和編寫就應避免垃圾對象的JVM內存佔用和GC的開銷。顯示調用System.GC()只能建議JVM需要在JVM內存中對垃圾對象進行回收,但不是必須馬上回收,一個是並不能解決JVM內存資源耗空的局面,另外也會增加GC的消耗。

◆當一個URL被訪問時,JVM內存區域申請過程如下:

A.JVM會試圖為相關Java對象在Eden中初始化一塊JVM內存區域

B.當Eden空間足夠時,JVM內存申請結束。否則到下一步

C.JVM試圖釋放在Eden中所有不活躍的對象(這屬於1或更高級的垃圾回收),釋放後若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區

D.Survivor區被用來作為Eden及OLD的中間交換區域,當OLD區空間足夠時,Survivor區的對象會被移到Old區,否則會被保留在Survivor區

E.當OLD區空間不夠時,JVM會在OLD區進行完全的垃圾收集(0級)

F.完全垃圾收集後,若Survivor及OLD區仍然無法存放從Eden復制過來的部分對象,導致JVM無法在Eden區為新對象創建JVM內存區域,則出現"outofmemory錯誤"

㈩ Java數組是存儲在內存中的什麼地方

因為我也不清楚你理解的內存指啥,說我的理解,猜測一下,但願符合你的理解:
對程序而言,內存分為:
a、靜態區塊或叫全局區塊,指程序載入的時候就分配的固定存儲區;
b、棧內存,代碼塊執行的時候動態分配的內存塊,代碼運行完後,操作系統或運行平台負責自動回收這部分使用的內存。
c、堆內存塊,由操作系統提供api程序自由分配管理的內存塊。
java的內存管理機制,我個人認為是黑盒的,寫java也很少有人去關心,但是如果看虛擬機的實現源碼還是能知道的。(樓主懂c由興趣自己看)。那麼從逆向工程的角度我們可以猜測到:
靜態類,靜態變數,存儲在,靜態區塊中。
類本身代碼需要時再載入到內存中,java的動態代理實現的根本。既然是動態載入肯定是在堆中,不過載入進來的類代碼可能永不會銷毀(虛擬機運行區間內,可以加快運行平台的處理速度,java屬於半編譯半解釋的一門語言,要解釋執行的是預先編譯好的指令,就是class類文件)。
我們創建的任何對象,時間是隨機的,創建的時候才會分配內存,必然在堆上。虛擬機的垃圾回收機制要管理的剛好是這部分內存。
類中的方法,或靜態代碼塊必定運行在占上,代碼運行完,內存立即回收。此處有個例外,不同於c語言或操作系統實現。在方法中返回的任何對象:c需要動態分配存儲空間,兵自行管理,或者申明為全局局部靜態存儲,代碼運行完,對象才能保留下來。java可以直接保留下來。說明虛擬機自動給我們申請了動態內存保存對象。此處分配的內存也需要垃圾回收機制管理。沒門語言都有原始類型,方法或函數中返回的原始類型不需要從堆上分配內存,直接復制給接收變數,或代碼運行的形參所分配的空間中即可。
從操作系統理解,內存分為內核使用的內存與程序使用的內存,java運行在虛擬機上,虛擬機運行在操作系統上,內核內存屬於操作系統自用內存,由操作系統負責管理,運用程序不能直接管理分配內核內存。應用程序可管理的是分配給自己的運行空間。因此java使用內存屬於應用程序內存。內核內存管理方式windows與unix實現管理方式不一樣,最大差別windows的每一個程序,內核需要使用掉一部分地址空間,餘下的留給應用程序。如32位系統,總共可以使用的地址空間是4G內核要用掉其中1G或者2G。但是unix實現的系統應用程序可以直接使用4G地址空間。有興趣請參考操作系統內核相關書籍。

熱點內容
linux命令包 發布:2025-01-10 23:54:26 瀏覽:31
python輪廓 發布:2025-01-10 23:49:23 瀏覽:177
思科配置線怎麼選 發布:2025-01-10 23:48:44 瀏覽:703
解壓水晶泥 發布:2025-01-10 23:27:23 瀏覽:634
小米攝像頭如何改wifi密碼 發布:2025-01-10 23:25:14 瀏覽:113
阿里雲伺服器首頁 發布:2025-01-10 23:24:15 瀏覽:435
win2003單網卡搭建vpn伺服器搭建 發布:2025-01-10 23:21:13 瀏覽:355
如何製作原始傳奇腳本 發布:2025-01-10 23:00:30 瀏覽:118
小程序免費模板源碼下載 發布:2025-01-10 22:55:23 瀏覽:234
gradle編譯jar 發布:2025-01-10 22:54:36 瀏覽:797