今天我們來談一談java程序在內(nèi)存之中的執(zhí)行過程,掌握程序在內(nèi)存中的執(zhí)行過程是至關(guān)重要的,所以本人開始從簡單的程序入手一點點解析內(nèi)存中的程序是怎么執(zhí)行的,廢話不多說先上一段代碼。
public class TestArray1{
/*
selectSorting
*/
public static void main(String[] args){
int[] a = new int[args.length];
for(int i=0;i<args.length;i++){
a[i] = Integer.parseInt(args[i]);
}
printSort(a);
selectSort(a);
printSort(a);
}
private static void selectSort(int[] a){
int k,temp;
for(int i=0;i<a.length;i++){
k = i;
for(int j=k+1;j<a.length;j++){
if(a[j]<a[k]){
k = j;
}
}
if(k != i){
temp = a[i];
a[i]=a[k];
a[k]=temp;
}
}
}
private static void printSort(int[] a){
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
System.out.println();
}
}
很簡單的一段小程序,首先分析內(nèi)存我們肯定是從main方法開始分析,那么接下來我們從main方法開始一句一句分析代碼在內(nèi)存之中的執(zhí)行過程。首先看main方法第一句
int[] a = new int[args.length];
這句話很簡單,我們new了一個新的數(shù)組然后這個數(shù)組的內(nèi)容是args.length, 那么args.length是多長呢,首先我們要知道m(xù)ain方法中的String[] args這個數(shù)組是干什么用的,這個數(shù)組相當(dāng)于是一個備用數(shù)組當(dāng)我們在編譯完程序之后在執(zhí)行程序前輸入的各個數(shù)據(jù)會被放到這個數(shù)組之中,如圖所示:

我們在執(zhí)行程序時在后面輸入的各個數(shù)據(jù)將會被存入到這個數(shù)組里面中間那需要用空格隔開。那么我們接著分析內(nèi)存:
我們這里new了一個新的數(shù)組這個時候內(nèi)存之中的執(zhí)行過程是,從??臻g里面分配一塊空間a 這個a多大我不知道,我知道我通過這個a可以找到堆內(nèi)存中的一個int數(shù)組并且它的長度是args.length

從圖上我們可以明確的看到??臻g里面的一個a指向了堆空間里的一個int數(shù)組并且數(shù)組的長度是args.length,然后我們接著往下看代碼執(zhí)行
for(int i=0;i<args.length;i++){
a[i] = Integer.parseInt(args[i]);
}
我們這里走了一個for循環(huán),我們可以看到我們這里將args這個數(shù)組里面存儲的所有數(shù)據(jù)都放到了a這個數(shù)組里面,內(nèi)存之中只是將a指向的這個數(shù)組裝滿了數(shù)據(jù),相當(dāng)于我們將一個空桶裝滿了水,然后我們接著看后面的執(zhí)行,下面執(zhí)行了printSort這個方法我們看printSort這個方法都做了哪些操作。
private static void printSort(int[] a){
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
System.out.println();
}
我們可以明確的看到printSort方法是將a數(shù)組里面的數(shù)據(jù)一一的輸出出來。然后我們接著看selectSort這個方法,此程序的重點就在selectSort方法,selectSort方法主要是做了排序的操作,
private static void selectSort(int[] a){
int k,temp;
for(int i=0;i<a.length;i++){
k = i;
for(int j=k+1;j<a.length;j++){
if(a[j]<a[k]){
k = j;
}
}
if(k != i){
temp = a[i];
a[i]=a[k];
a[k]=temp;
}
}
}
我們就主要看看排序是怎么從內(nèi)存之中執(zhí)行的。首先我們看到selectSort方法第一步先定義了兩個int類型的變量k,和temp并且沒有賦值,如果我們沒有賦值的話,那么java會自動設(shè)置默認(rèn)值,int類型的默認(rèn)值是0至于其他類型的可以自己去查詢api文檔這里不過多說,接下來我們看圖說話:

我們可以看到,在??臻g中分配了兩塊內(nèi)存k和temp并且初始值都是0.
程序接著向下執(zhí)行
for(int i=0;i<a.length;i++){
k = i;
for(int j=k+1;j<a.length;j++){
if(a[j]<a[k]){
k = j;
}
}
if(k != i){
temp = a[i];
a[i]=a[k];
a[k]=temp;
}
}
這里執(zhí)行了一個雙重的for循環(huán),雙重循環(huán)或者是多重循環(huán)都是從里往外執(zhí)行所以先執(zhí)行里面的for循環(huán)在執(zhí)行外面的for循環(huán),首先是k=i
那么這里就是將i的值賦值給了k,接下來我們看里面的循環(huán)
for(int j=k+1;j<a.length;j++){
if(a[j]<a[k]){
k = j;
}
}
這里的j初始值是k+1就相當(dāng)于當(dāng)i=0時,j=1,當(dāng)i=1,j=2以此類推
if(a[j]<a[k]){
k = j;
}
并且我們需要注意這里是將i的值賦值給了k所以此時k在??臻g里存儲的值是i,然后這里a[j]和a[k]做了一個比較并且將下標(biāo)值進(jìn)行了更換。此時只是進(jìn)行前一個值和后一個值進(jìn)行比較經(jīng)過此次的for循環(huán)我們可以知道這個數(shù)組之中最小數(shù)的下標(biāo)值是多少,然后在進(jìn)行和i的比較看看這個最小數(shù)的下標(biāo)值是不是等于i如果等于i那么正好就不需要調(diào)換位置
if(k != i){
temp = a[i];
a[i]=a[k];
a[k]=temp;
}
如果這個最小值的下標(biāo)值和i不相等那么我們就需要將這個最小值的下標(biāo)值賦值給i這個位置,我們這里需要注意的是i也是下標(biāo)值
當(dāng)我們執(zhí)行完這個循環(huán)之后此時的內(nèi)存如下圖所示:

這里的k和i都是下標(biāo)值temp只不過是臨時存儲了a[i],因為當(dāng)兩個數(shù)調(diào)換位置的話我們不能直接賦值我們需要一個第三個的容器來存儲其中的一個然后兩個才能進(jìn)行調(diào)換位置。當(dāng)我們的for循環(huán)完全執(zhí)行完之后此時的垃圾回收器將會馬上回收temp和k 這兩塊內(nèi)存此時的內(nèi)存如下圖

只剩下a指向堆內(nèi)存中的int數(shù)組并且此時的int數(shù)組已經(jīng)是從下到大排好序的所以此時selectSort方法執(zhí)行完畢然后main方法在執(zhí)行了printSort方法將排好序的數(shù)據(jù)進(jìn)行一一打印。如圖所示這就是我們最終的執(zhí)行結(jié)果

首先上面先打印的沒排好序的數(shù)組然后打印已經(jīng)排好序的內(nèi)容,基本上這段程序就執(zhí)行完了,執(zhí)行完之后垃圾回收器就會將這些內(nèi)存都回收了,程序挺簡單的主要就是內(nèi)存分析