java 數據保存內存_java中的各種數據類型在內存中存儲的方式 一

1.java是如何管理內存的

java的內存管理就是對象的分配和釋放問題。(其中包括兩部分)

分配:內存的分配是由程序完成的,程序員需要通過關鍵字new為每個對象申請內存空間(基本類型除外),所有的對象都在堆(Heap)中分配空間。釋放:對象的釋放是由垃圾回收機制決定和執行的,這樣做確實簡化了程序員的工作。但同時,它也加重了JVM的工作。因為,GC為了能夠正確釋放對象,GC必須監控每一個對象的運行狀態,包括對象的申請、引用、被引用、賦值等,GC都需要進行監控。

2.什么叫java的內存泄露

在java中,內存泄漏就是存在一些被分配的對象,這些對象有下面兩個特點,首先,這些對象是可達的,即在有向圖中,存在通路可以與其相連(也就是說仍存在該內存對象的引用);其次,這些對象是無用的,即程序以后不會再使用這些對象。如果對象滿足這兩個條件,這些對象就可以判定為Java中的內存泄漏,這些對象不會被GC所回收,然而它卻占用內存。

3.JVM的內存區域組成

java把內存分兩種:一種是棧內存,另一種是堆內存(1)在函數中定義的基本類型變量和對象的引用變量都在函數的棧內存中分配;(2)堆內存用來存放由new創建的對象和數組以及對象的實例變量。在函數(代碼塊)中定義一個變量時,java就在棧中為這個變量分配內存空間,當超過變量的作用域后,java會自動釋放掉為該變量所分配的內存空間;在堆中分配的內存由java虛擬機的自動垃圾回收器來管理堆和棧的優缺點

堆的優勢是可以動態分配內存大小,生存期也不必事先告訴編譯器,因為它是在運行時動態分配內存的。

缺點就是要在運行時動態分配內存,存取速度較慢;棧的優勢是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。

另外,棧數據可以共享。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。

4.java中數據在內存中是如何存儲的

a)基本數據類型

java的基本數據類型共有8種,即int,short,long,byte,float,double,boolean,char(注意,并沒有String的基本類型)。這種類型的定義是通過諸如int a = 3;long b = 255L;的形式來定義的。如int a = 3;這里的a是一個指向int類型的引用,指向3這個字面值。這些字面值的數據,由于大小可知,生存期可知(這些字面值定義在某個程序塊里面,程序塊退出后,字段值就消失了),出于追求速度的原因,就存在于棧中。

另外,棧有一個很重要的特殊性,就是存在棧中的數據可以共享。比如:我們同時定義:

int a=3;

int b=3;

編譯器先處理int a = 3;首先它會在棧中創建一個變量為a的引用,然后查找有沒有字面值為3的地址,沒找到,就開辟一個存放3這個字面值的地址,然后將a指向3的地址。接著處理int b = 3;在創建完b這個引用變量后,由于在棧中已經有3這個字面值,便將b直接指向3的地址。這樣,就出現了a與b同時均指向3的情況。

定義完a與b的值后,再令a = 4;那么,b不會等于4,還是等于3。在編譯器內部,遇到時,它就會重新搜索棧中是否有4的字面值,如果沒有,重新開辟地址存放4的值;如果已經有了,則直接將a指向這個地址。因此a值的改變不會影響到b的值。

b)對象

在java中,創建一個對象包括對象的聲明和實例化兩步,下面用一個例題來說明對象的內存模型。假設有類Rectangle定義如下:

1.publicclassRectangle{

2.doublewidth;

3.doubleheight;

4.publicRectangle(doublew,doubleh){

5.w=width;

6.h=height;

7.}

8.}

(1)聲明對象時的內存模型用Rectangle rect;聲明一個對象rect時,將在棧內存為對象的引用變量rect分配內存空間,但Rectangle的值為空,稱rect是一個空對象。空對象不能使用,因為它還沒有引用任何”實體”。(2)對象實例化時的內存模型當執行rect=new Rectangle(3,5);時,會做兩件事:在堆內存中為類的成員變量width,height分配內存,并將其初始化為各數據類型的默認值;接著進行顯式初始化(類定義時的初始化值);最后調用構造方法,為成員變量賦值。返回堆內存中對象的引用(相當于首地址)給引用變量rect,以后就可以通過rect來引用堆內存中的對象了。

c)創建多個不同的對象實例

一個類通過使用new運算符可以創建多個不同的對象實例,這些對象實例將在堆中被分配不同的內存空間,改變其中一個對象的狀態不會影響其他對象的狀態。例如:

1.Rectangler1=newRectangle(3,5);

2.Rectangler2=newRectangle(4,6);

此時,將在堆內存中分別為兩個對象的成員變量width、height分配內存空間,兩個對象在堆內存中占據的空間是互不相同的。如果有:

1.Rectangler1=newRectangle(3,5);

2.Rectangler2=r1;

則在堆內存中只創建了一個對象實例,在棧內存中創建了兩個對象引用,兩個對象引用同時指向一個對象實例。

d)包裝類

基本類型都有對應的包裝類:如int對應Integer類,double對應Double類等,基本類型的定義都是直接在棧中,如果用包裝類來創建對象,就和普通對象一樣了。例如:int i=0;i直接存儲在棧中。Integer i(i此時是對象)= newInteger(5);這樣,i對象數據存儲在堆中,i的引用存儲在棧中,通過棧中的引用來操作對象。

e)String

String是一個特殊的包裝類數據。可以用以下兩種方式創建:String str= new String(“abc”);String str = “abc”;第一種創建方式,和普通對象的的創建過程一樣;第二種創建方式,java內部將此語句轉化為以下幾個步驟:(1)先定義一個名為str的對String類的對象引用變量:String str;(2)在棧中查找有沒有存放值為”abc”的地址,如果沒有,則開辟一個存放字面值為”abc”地址,接著創建一個新的String類的對象o,并將o的字符串值指向這個地址,而且在棧這個地址旁邊記下這個引用的對象o。如果已經有了值為”abc”的地址,則查找對象o,并回o的地址。(3)將str指向對象o的地址。值得注意的是,一般String類中字符串值都是直接存值的。但像String str = “abc”;這種合下,其字符串值卻是保存了一個指向存在棧中數據的引用。為了更好地說明這個問題,我們可以通過以下的幾個代碼進行驗證。

1.Stringstr1="abc";

2.Stringstr2="abc";

3.System.out.println(s1==s2);//true

注意,這里并不用str1.equals(str2);的方式,因為這將比較兩個字符串的值是否相等。==號,根據JDK的說明,只有在兩個引用都指向了同一個對象時才返回真值。而我們在這里要看的是,str1與str2是否都指向了同一個對象。我們再接著看以下的代碼。

1.Stringstr1=newString("abc");

2.Stringstr2="abc";

3.System.out.println(str1==str2);//false

創建了兩個引用。創建了兩個對象。兩個引用分別指向不同的兩個對象。以上兩段代碼說明,只要是用new()來新建對象的,都會在堆中創建,而且其字符串是單獨存值的,即使與棧中的數據相同,也不會與棧中的數據共享。

f)數組

當定義一個數組,int x[];或int[] x;時,在棧內存中創建一個數組引用,通過該引用(即數組名)來引用數組。x=newint[3];將在堆內存中分配3個保存int型數據的空間,堆內存的首地址放到棧內存中,每個數組元素被初始化為0。

g)靜態變量

用static的修飾的變量和方法,實際上是指定了這些變量和方法在內存中的”固定位置”-static storage,可以理解為所有實例對象共有的內存空間。static變量有點類似于C中的全局變量的概念;靜態表示的是內存的共享,就是它的每一個實例都指向同一個內存地址。把static拿來,就是告訴JVM它是靜態的,它的引用(含間接引用)都是指向同一個位置,在那個地方,你把它改了,它就不會變成原樣,你把它清理了,它就不會回來了。

那靜態變量與方法是在什么時候初始化的呢?對于兩種不同的類屬性,static屬性與instance屬性,初始化的時機是不同的。instance屬性在創建實例的時候初始化,static屬性在類加載,也就是第一次用到這個類的時候初始化,對于后來的實例的創建,不再次進行初始化。

我們常可看到類似以下的例子來說明這個問題:

1.classStudent{

2.staticintnumberOfStudents=0;

3.Student()

4.{

5.numberOfStudents++;

6.}

7.}

每一次創建一個新的Student實例時,成員numberOfStudents都會不斷的遞增,并且所有的Student實例都訪問同一個numberOfStudents變量,實際上intnumberOfStudents變量在內存中只存儲在一個位置上。

5.java的內存管理實例

Java程序的多個部分(方法,變量,對象)駐留在內存中以下兩個位置:即堆和棧,現在我們只關心三類事物:實例變量,局部變量和對象:實例變量和對象駐留在堆上局部變量駐留在棧上讓我們查看一個java程序,看看他的各部分如何創建并且映射到棧和堆中:

1.publicclassDog{

2.Collarc;

3.Stringname;

4.//1.main()方法位于棧上

5.publicstaticvoidmain(String[]args){

6.//2.在棧上創建引用變量d,但Dog對象尚未存在

7.Dogd;

8.//3.創建新的Dog對象,并將其賦予d引用變量

9.d=newDog();

10.//4.將引用變量的一個副本傳遞給go()方法

11.d.go(d);

12.}

13.//5.將go()方法置于棧上,并將dog參數作為局部變量

14.voidgo(Dogdog){

15.//6.在堆上創建新的Collar對象,并將其賦予Dog的實例變量

16.c=newCollar();

17.}

18.//7.將setName()添加到棧上,并將dogName參數作為其局部變量

19.voidsetName(StringdogName){

20.//8.name的實例對象也引用String對象

21.name=dogName;

22.}

23.//9.程序執行完成后,setName()將會完成并從棧中清除,此時,局部變量dogName也會消失,盡管它所引用的String仍在堆上

24.}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/539641.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/539641.shtml
英文地址,請注明出處:http://en.pswp.cn/news/539641.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Gradle學習之構建java與web項目

一.使用Gradle的java插件構建Java項目 1)Gradle插件包含了若干個接口定義和已有的任務項,語法結構:apply plugin:插件名 ,此處我們定義插件 apply plugin : java 2)Gradle希望我們的java項目需要遵循以下規范: src/mai…

Hibernate單表開發步驟

Hibernate單邊開發步驟: 1、創建Configuration,加載src/hibernate.cfg.xml配置文件,該配置文件中又去加載Hello.hbm.xml映射文件。 2、通過Configuration創建重量級SessionFactory。重量級:創建慢,內存占用大&#…

基于ssm出租車管理系統的設計與實現論文

摘 要 現代經濟快節奏發展以及不斷完善升級的信息化技術,讓傳統數據信息的管理升級為軟件存儲,歸納,集中處理數據信息的管理方式。本出租車管理系統就是在這樣的大環境下誕生,其可以幫助管理者在短時間內處理完畢龐大的數據信息&…

redission java_Java注解如何基于Redission實現分布式鎖

這篇文章主要介紹了Java注解如何基于Redission實現分布式鎖,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下1、定義注解類Target({ ElementType.METHOD })Retention(RetentionPolicy.RUNTIME)Documentedpublic i…

Spring Security源碼分析四:Spring Social實現微信社交登錄

2019獨角獸企業重金招聘Python工程師標準>>> 社交登錄又稱作社會化登錄(Social Login),是指網站的用戶可以使用騰訊QQ、人人網、開心網、新浪微博、搜狐微博、騰訊微博、淘寶、豆瓣、MSN、Google等社會化媒體賬號登錄該網站。 前言…

jdbc開發優缺點

1)優點:簡單易學,上手快,非常靈活構建SQL,效率高 2)缺點:代碼繁瑣,難以寫出高質量的代碼(例如:資源的釋放,SQL注入安全性等) 開發者既要寫業務邏輯&#xff0…

java numberformat 方法_Java NumberFormat parse()用法及代碼示例

parse(str)方法是java.text.NumberFormat的內置方法,該方法從給定字符串的開頭解析文本以產生數字。該方法可能不使用給定字符串的整個文本用法:public Number parse?(String str)參數:該函數接受一個字符串str,其開頭應進行分析。返回值&am…

hibernate開發優缺點

1)優點:不用寫SQL,完全以面向對象的方式設計和訪問,不用管底層具體數據庫的語法,(例如:分頁)便于理解。 2)缺點:處理復雜業務時,靈活度差, 復雜的…

求方程的解 Solve the Equation

為什么80%的碼農都做不了架構師?>>> 問題: Solve a given equation and return the value of x in the form of string "x#value". The equation contains only , - operation, the variable x and its coefficient. If there is …

[C#學習] DataAdapter.Fill()分頁

查詢結果分頁是以較小數據子集(即頁)的形式返回查詢結果的過程。 它通常用于以易于管理的小塊形式向用戶顯示結果。DataAdapter 提供了通過 Fill 方法的重載來僅返回一頁數據的功能。 但是,對于大量的查詢結果,它可能并不是首選的…

java流讀取字符串_javaIO之字符流是怎么讀取的?

最近在看io相關的知識,遇到一些小問題,以下有例子來說明問題:比如:12345 是一個十進制數根據ASCII碼找到是 :二進制 00110001 00110010 00110011 00110100 00110101十進制4950515253十六進制 0x310x320x330x340x35文件…

什么是mybatis,mybatis有什么特點

jdbc開發優缺點:http://blog.csdn.net/zengmingen/article/details/51180796 hibernate開發優缺點:http://blog.csdn.net/zengmingen/article/details/51180805 1)基于上述二種支持,我們需要在中間找到一個平衡點呢?結…

簡易RPC框架實現

寫在最前面 PRC(Remote Procedure Call) 遠程過程調用。通俗的講就是程序通過RPC框架調用遠程主機的方法就如同調用本地方法一樣。Dubbo就是這樣一個Rpc框架,本文主要參考Dubbo的設計思路,簡易實現了Rpc框架。 本文涉及到知識點包括: Jdk 動態…

kafka java獲取topic_通過編程方式獲取Kafka中Topic的Metadata信息

如果我們需要通過編程的方式來獲取到TopicMetadataRequest請求到 def findLeader(topic: String): Unit {val consumer connect("www.iteblog.com", 9092)val req TopicMetadataRequest(TopicMetadataRequest.CurrentVersion,0, kafkaGroupId, List(topic))val to…

redis java 遍歷key_java遍歷讀取整個redis數據庫實例

redis提供了靈活的數據查詢方式,最牛的就是key的搜索支持正則表達式。jedis.keys(“*”);表示搜索所有keyjedis.keys(“abc*”)表示搜索開頭為abc的key數據遍歷了key就能遍歷到value。其實就是一個setRedisDO rd new RedisDO();rd.open();Set s rd.jedis.keys(&qu…

js學習

為什么80%的碼農都做不了架構師?>>> /* my code */ var gArrSpell [ 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 999999, AAAA, bbbb, cccc, dddd, eeee, fffff ];var gArrSplDmg [11,12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24…

代碼在eclipse下不報錯,在doc命令行下報錯--jar file和runable jar file

今天開發一個小工具,引用了Log4j,來記錄日志,在eclipse下運行,代碼正常,打包成jar放到doc命令行下運行報錯: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/…

gradle java ide_使用Gradle構建Java項目

使用Gradle構建Java項目這個手冊將通過一個簡單的Java項目向大家介紹如何使用Gradle構建Java項目。我們將要做什么?我們將在這篇文檔航中創建一個簡單的Java項目,然后使用Gradle構建它。需要準備什么?預留15分鐘空閑時間一件稱手的兵器(你最喜…

小馬激活軟件下載,當心偽小馬,有病毒

官方的小馬激活軟件已經停止更新了,下文是官方停更公告。 http://www.pccppc.com/xiaomajihuo-html 所以小馬oem7以后的都不是官方的,包含病毒。重裝系統后,一般是先激活系統,再安裝殺毒軟件,這就給“偽小馬激活工具”…

truncate,delete,drop之間的區別

TRUNCATE TABLE 在功能上與不帶 WHERE 子句的 DELETE 語句相同:二者均刪除表中的全部行。 但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系統和事務日志資源少。 DELETE 語句每次刪除一行,并在事務日志中為所刪除的每行記錄一項。 TRUNCATE…