成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

JAVA內(nèi)存管理-創(chuàng)新互聯(lián)

被問到有關(guān)Java內(nèi)存管理的知識,所以要搜集整理一下了。開始之前,我們要明白一點(diǎn),我們所使用的變量就是一塊一塊的內(nèi)存空間??!

創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷、網(wǎng)站重做改版、建平網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5頁面制作、商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價格優(yōu)惠性價比高,為建平等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

一、內(nèi)存管理原理:

在java中,有java程序、虛擬機(jī)、操作系統(tǒng)三個層次,其中java程序與虛擬機(jī)交互,而虛擬機(jī)與操作系統(tǒng)間交互!這就保證了java程序的平臺無關(guān)性!下面我們從程序運(yùn)行前,程序運(yùn)行中、程序運(yùn)行內(nèi)存溢出三個階段來說一下內(nèi)存管理原理!1、程序運(yùn)行前:JVM向操作系統(tǒng)請求一定的內(nèi)存空間,稱為初始內(nèi)存空間!程序執(zhí)行過程中所需的內(nèi)存都是由java虛擬機(jī)從這片內(nèi)存空間中劃分的。2、程序運(yùn)行中:java程序一直向java虛擬機(jī)申請內(nèi)存,當(dāng)程序所需要的內(nèi)存空間超出初始內(nèi)存空間時,java虛擬機(jī)會再次向操作系統(tǒng)申請更多的內(nèi)存供程序使用!3、內(nèi)存溢出:程序接著運(yùn)行,當(dāng)java虛擬機(jī)已申請的內(nèi)存達(dá)到了規(guī)定的大內(nèi)存空間,但程序還需要更多的內(nèi)存,這時會出現(xiàn)內(nèi)存溢出的錯誤!至此可以看出,Java 程序所使用的內(nèi)存是由 Java 虛擬機(jī)進(jìn)行管理、分配的。Java 虛擬機(jī)規(guī)定了 Java 程序的初始內(nèi)存空間和大內(nèi)存空間,開發(fā)者只需要關(guān)心 Java 虛擬機(jī)是如何管理內(nèi)存空間的,而不用關(guān)心某一種操作系統(tǒng)是如何管理內(nèi)存的。     二、 RUNTIME 類的使用:  Java 給我們提供了Runtime 類得到JVM 內(nèi)存的信息
 方法名稱 參數(shù)作用返回值
 getRuntime 無 獲取 Runtime 對象 Runtime 對象
 totalMemory 無 獲取 JVM 分配給程序的內(nèi)存數(shù)量 long:內(nèi)存數(shù)量
 freeMemory 無 獲取 當(dāng)前可用的內(nèi)存數(shù)量 long:內(nèi)存數(shù)量
 maxMemory 無 獲取 JVM 可以申請到的大內(nèi)存數(shù)量 long:內(nèi)存數(shù)量
     三、內(nèi)存空間邏輯劃分:  JVM 會把申請的內(nèi)存從邏輯上劃分為三個區(qū)域,即:方法區(qū)、堆與棧。 方法區(qū):方法區(qū)默認(rèn)大容量為64M,Java虛擬機(jī)會將加載的java類存入方法區(qū),保存類的結(jié)構(gòu)(屬性與方法),類靜態(tài)成員等內(nèi)容。堆:默認(rèn)大容量為64M,堆存放對象持有的數(shù)據(jù),同時保持對原類的引用??梢院唵蔚睦斫鉃閷ο髮傩缘闹当4嬖诙阎校瑢ο笳{(diào)用的方法保存在方法區(qū)。:棧默認(rèn)大容量為1M,在程序運(yùn)行時,每當(dāng)遇到方法調(diào)用時,Java虛擬機(jī)就會在棧中劃分一塊內(nèi)存稱為棧幀(Stack frame),棧幀中的內(nèi)存供局部變量(包括基本類型與引用類型)使用,當(dāng)方法調(diào)用結(jié)束后,Java虛擬機(jī)會收回此棧幀占用的內(nèi)存。   四、java數(shù)據(jù)類型    1、基本數(shù)據(jù)類型:沒封裝指針的變量。聲明此類型變量,只會在棧中分配一塊內(nèi)存空間。 2、引用類型:就是底層封裝指針的數(shù)據(jù)類型。他們在內(nèi)存中分配兩塊空間,第一塊內(nèi)存分配在棧中,只存放別的內(nèi)存地址,不存放具體數(shù)值,我們也把它叫指針類型的變量,第二塊內(nèi)存分配在堆中,存放的是具體數(shù)值,如對象屬性值等。  3、下面我們從一個例子來看一看:
public class Student { 

  String stuId; 

  String stuName; 

int stuAge; 

} 

 


public class TestStudent { 

public static void main(String[] args) { 

    Student s= new Student(); 

    String name= new String("云鶴");  

int a = 10; 

char b = 'm'; 

    s.stuId= "6363"; 

    s.stuName= "劉德華"; 

    s.stuAge= 25; 

  } 

}

(1)類當(dāng)然是存放在方法區(qū)里面的。

(2)Student s = new Student(); 這行代碼就創(chuàng)建了兩塊內(nèi)存空間,第一個在棧中,名字叫s,它就相當(dāng)于指針類型的變量,我們看到它并不存放學(xué)生的姓名、年齡等具體的數(shù)值,而是存放堆中第二塊內(nèi)存的地址,第二塊才存放具體的數(shù)值,如學(xué)生的編號、姓名、年齡等信息。  (3)int a = 10; 這是 基本數(shù)據(jù)類型 變量,具體的值就存放在棧中,并沒有只指針的概念!   下圖就是本例的內(nèi)存布置圖:   此外我們還要知道Student s = new Student(); 包括了聲明和創(chuàng)建,即:聲明:Student s;創(chuàng)建:s = new Student();其中聲明只是在棧中聲明一個空間,但還沒有具體的值,聲明后的情況如下圖所示: 創(chuàng)建后的情況如下圖所示:     (4)引用類型中的數(shù)組也封裝了指針,即便是基本數(shù)據(jù)類型的數(shù)組也封裝了指針,數(shù)組也是引用類型。比如代碼int[] arr = new int[]{3, 6, 12, 9, 66, 31};如下圖所示:  五、java值傳參與引用傳參   (1)參數(shù)根據(jù)調(diào)用后的效果不同,即是否改變參數(shù)的原始數(shù)值,又可以分為兩種:按值傳遞的參數(shù)按引用傳遞的參數(shù)。 按值傳遞的參數(shù)原始數(shù)值不改變,按引用傳遞的參數(shù)原始數(shù)值改變!這是為什么呢?其實(shí)相當(dāng)簡單: 我們知道基本數(shù)據(jù)類型的變量存放在棧里面,變量名處存放的就是變量的值,那么當(dāng)基本數(shù)據(jù)類型的變量作為參數(shù)時,傳遞的就是這個值,只是把變量的值傳遞了過去,不管對這個值如何操作,都不會改變變量的原始值。而對引用數(shù)據(jù)類型的變量來說,變量名處存放的地址,所以引用數(shù)據(jù)類型的變量作為傳參時,傳遞的實(shí)際上是地址,對地址處的內(nèi)容進(jìn)行操作,當(dāng)然會改變變量的值了! 正常情況下,我們用數(shù)組測試TestArray類如下:
public class TestArray { 

void change(int[] arr) { 

for(int i=0;i<arr.length;i++)
if(i%2==0)
                   arr[i]=1000;
            System.out.println("方法體內(nèi)修改值后:" ); 
for(int i=0;i<arr.length;i++)
                System.out.println(arr[i]);
      }

public static void main(String[] args) { 


int[] a = {1,2,3,4}; 

    TestArray testString= new TestArray(); 

    System.out.println("方法調(diào)用前:"); 
for(int i=0;i<a.length;i++)
        System.out.println(a[i]);
    testString.change(a); 
    System.out.println("方法調(diào)用后:"); 
for(int i=0;i<a.length;i++)
        System.out.println(a[i]);
  } 

    }

輸出結(jié)果如下:

方法調(diào)用前:
1234
方法體內(nèi)修改值后:
1000210004
方法調(diào)用后:
1000210004

數(shù)組實(shí)際上也是引用類型,在調(diào)用函數(shù)的過程中改變了其值。

 (2)特例:String

 
public class TestString { 

void change(String str) { 

            str= "吳奇隆"; 

            System.out.println("方法體內(nèi)修改值后:" + str); 
    
      }

public static void main(String[] args) { 


    String name= "歌星"; 

    TestString testString= new TestString(); 

    System.out.println("方法調(diào)用前:" + name); 
    testString.change(name); 
    System.out.println("方法調(diào)用后:" + name); 

  } 

結(jié)果:

方法調(diào)用前:歌星
方法體內(nèi)修改值后:吳奇隆
方法調(diào)用后:歌星

分析:

上例中,雖然參數(shù)String 是引用數(shù)據(jù)類型,但其值沒有發(fā)生改變,這是因?yàn)镾tring 類是final 的,它是定長,不允許對其進(jìn)行改變,而StringBuffer(多線程下使用性能優(yōu))和StringBuilder(單線程下面使用性能優(yōu))是可以改變的。如果這里用StringBuffer和SringBuiler替代,結(jié)果和Array的使用一樣,中間結(jié)果會被改變。 我們看初始情況,即String name = "歌星";這行代碼運(yùn)行 完,如下圖:      當(dāng)調(diào)用方法時testString.change(name),內(nèi)存變化為:       在方法體內(nèi),參數(shù)str賦予一個新值,str = "吳奇隆"。因?yàn)?吳奇隆"這個String是定長,系統(tǒng)就會在堆中分配一塊新的內(nèi)存空間37DF,這樣str指向了新的內(nèi)存空間37DF,而name還是指向36DF, 37DF的改變對它已沒影響:     最后,方法調(diào)用結(jié)束,str與37DF的內(nèi)存空間消亡。Name的值依然為歌星,并沒有改變。 所以String雖然是引用類型參數(shù),但值依然不變:      (3)無法交換的例子:  
public class TestChange { 

void change(Student stu1, Student stu2) { 

    stu1.stuAge++; 

    stu2.stuAge++; 

    Student stu= stu1; 

    stu1= stu2; 

    stu2= stu; 

  } 

   

public static void main(String[] args) { 

     

    Student z= new Student(); 

    z.stuName= "張信哲"; 

    z.stuAge= 40; 

     

    Student r= new Student(); 

    r.stuName= "任賢齊"; 

    r.stuAge= 30; 

    System.out.println("交換前z:	"+z.stuName+"	"+z.stuAge); 
    System.out.println("交換前r:	"+r.stuName+"	"+r.stuAge); 

    TestChange testChange= new TestChange(); 

    testChange.change(z, r);      

    System.out.println("交換后z:	"+z.stuName+"	"+z.stuAge); 
    System.out.println("交換后r:	"+r.stuName+"	"+r.stuAge); 

  } 
  
}

運(yùn)行結(jié)果:

交換前z:    張信哲  40
交換前r:    任賢齊30
交換后z:    張信哲41
交換后r:    任賢齊31

 

網(wǎng)站欄目:JAVA內(nèi)存管理-創(chuàng)新互聯(lián)
本文鏈接:http://jinyejixie.com/article16/ccscgg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、ChatGPT網(wǎng)站排名、網(wǎng)站設(shè)計(jì)、全網(wǎng)營銷推廣、網(wǎng)頁設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)
紫金县| 安吉县| 平泉县| 吉木乃县| 巨鹿县| 阳朔县| 宝丰县| 察哈| 醴陵市| 承德县| 崇左市| 丹东市| 黄山市| 桃江县| 开平市| 类乌齐县| 灯塔市| 阿拉善左旗| 天全县| 靖西县| 合川市| 桂阳县| 鄱阳县| 黎城县| 正镶白旗| 通河县| 额尔古纳市| 汕尾市| 临沭县| 灯塔市| 青海省| 嵊州市| 桑日县| 呼玛县| 宝鸡市| 柳林县| 英德市| 墨脱县| 盘山县| 九江市| 宜昌市|