bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

JAVA內存管理-創新互聯

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

創新互聯專注于企業成都全網營銷、網站重做改版、建平網站定制設計、自適應品牌網站建設、H5頁面制作商城網站建設、集團公司官網建設、外貿網站制作、高端網站制作、響應式網頁設計等建站業務,價格優惠性價比高,為建平等各大城市提供網站開發制作服務。

一、內存管理原理:

在java中,有java程序、虛擬機、操作系統三個層次,其中java程序與虛擬機交互,而虛擬機與操作系統間交互!這就保證了java程序的平臺無關性!下面我們從程序運行前,程序運行中、程序運行內存溢出三個階段來說一下內存管理原理!1、程序運行前:JVM向操作系統請求一定的內存空間,稱為初始內存空間!程序執行過程中所需的內存都是由java虛擬機從這片內存空間中劃分的。2、程序運行中:java程序一直向java虛擬機申請內存,當程序所需要的內存空間超出初始內存空間時,java虛擬機會再次向操作系統申請更多的內存供程序使用!3、內存溢出:程序接著運行,當java虛擬機已申請的內存達到了規定的大內存空間,但程序還需要更多的內存,這時會出現內存溢出的錯誤!至此可以看出,Java 程序所使用的內存是由 Java 虛擬機進行管理、分配的。Java 虛擬機規定了 Java 程序的初始內存空間和大內存空間,開發者只需要關心 Java 虛擬機是如何管理內存空間的,而不用關心某一種操作系統是如何管理內存的。     二、 RUNTIME 類的使用:  Java 給我們提供了Runtime 類得到JVM 內存的信息
 方法名稱 參數作用返回值
 getRuntime 無 獲取 Runtime 對象 Runtime 對象
 totalMemory 無 獲取 JVM 分配給程序的內存數量 long:內存數量
 freeMemory 無 獲取 當前可用的內存數量 long:內存數量
 maxMemory 無 獲取 JVM 可以申請到的大內存數量 long:內存數量
     三、內存空間邏輯劃分:  JVM 會把申請的內存從邏輯上劃分為三個區域,即:方法區、堆與棧。 方法區:方法區默認大容量為64M,Java虛擬機會將加載的java類存入方法區,保存類的結構(屬性與方法),類靜態成員等內容。堆:默認大容量為64M,堆存放對象持有的數據,同時保持對原類的引用。可以簡單的理解為對象屬性的值保存在堆中,對象調用的方法保存在方法區。:棧默認大容量為1M,在程序運行時,每當遇到方法調用時,Java虛擬機就會在棧中劃分一塊內存稱為棧幀(Stack frame),棧幀中的內存供局部變量(包括基本類型與引用類型)使用,當方法調用結束后,Java虛擬機會收回此棧幀占用的內存。   四、java數據類型    1、基本數據類型:沒封裝指針的變量。聲明此類型變量,只會在棧中分配一塊內存空間。 2、引用類型:就是底層封裝指針的數據類型。他們在內存中分配兩塊空間,第一塊內存分配在棧中,只存放別的內存地址,不存放具體數值,我們也把它叫指針類型的變量,第二塊內存分配在堆中,存放的是具體數值,如對象屬性值等。  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)類當然是存放在方法區里面的。

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

    }

輸出結果如下:

方法調用前:
1234
方法體內修改值后:
1000210004
方法調用后:
1000210004

數組實際上也是引用類型,在調用函數的過程中改變了其值。

 (2)特例:String

 
public class TestString { 

void change(String str) { 

            str= "吳奇隆"; 

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

public static void main(String[] args) { 


    String name= "歌星"; 

    TestString testString= new TestString(); 

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

  } 

結果:

方法調用前:歌星
方法體內修改值后:吳奇隆
方法調用后:歌星

分析:

上例中,雖然參數String 是引用數據類型,但其值沒有發生改變,這是因為String 類是final 的,它是定長,不允許對其進行改變,而StringBuffer(多線程下使用性能優)和StringBuilder(單線程下面使用性能優)是可以改變的。如果這里用StringBuffer和SringBuiler替代,結果和Array的使用一樣,中間結果會被改變。 我們看初始情況,即String name = "歌星";這行代碼運行 完,如下圖:      當調用方法時testString.change(name),內存變化為:       在方法體內,參數str賦予一個新值,str = "吳奇隆"。因為"吳奇隆"這個String是定長,系統就會在堆中分配一塊新的內存空間37DF,這樣str指向了新的內存空間37DF,而name還是指向36DF, 37DF的改變對它已沒影響:     最后,方法調用結束,str與37DF的內存空間消亡。Name的值依然為歌星,并沒有改變。 所以String雖然是引用類型參數,但值依然不變:      (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); 

  } 
  
}

運行結果:

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

 

網站欄目:JAVA內存管理-創新互聯
本文鏈接:http://vcdvsql.cn/article16/ccscgg.html

成都網站建設公司_創新互聯,為您提供微信小程序ChatGPT網站排名網站設計全網營銷推廣網頁設計公司

廣告

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

成都定制網站建設