java的内存分析

来源:互联网 发布:js触发click事件 a标签 编辑:程序博客网 时间:2024/06/05 22:46
分享到...
复制网址邮件QQ空间新浪微博腾讯微博微信人人网开心网网易微博搜狐微博QQ好友淘江湖飞信豆瓣一键分享查看更多(124)
这是什么工具?
JiaThis
分享到各大网站
一键分享猜你喜欢复制网址收藏夹打印邮件QQ空间新浪微博微信腾讯微博搜狐微博网易微博人人网开心网Google+轻笔记淘江湖豆瓣朋友网麦库记事百度搜藏有道云笔记手机快传天涯社区飞信百度贴吧凤凰微博优士网饭否点点网明道中搜v商奇乐收藏谷歌谷歌Buzz有道书签QQ好友QQ书签MSNPinterest花瓣网堆糖粉丝网摇篮微博115收藏百度空间Gmail邮箱Hotmail邮箱雪球和讯南方微博139邮箱189邮箱爱分享WO+分享翼友圈移动微博人民微博中金微博新华微博财迷谷歌翻译推他猫扑推客嘀咕网鲜果发现啦赶牛网米聊搜狐随身看51社区凤凰快博法律微博光明网人间网雷猴网和讯微博游戏江湖玛撒网宾至网FacebookTwitterTumblrRedditInstapaperPocket若邻网乐收挖客网创业邦救救地球抽屉网递客网豆瓣9点美丽说蘑菇街天际网Poco网宝盒网易集网Pdf在线转换友好打印W3c验证Bit.lyDiggMail.ruDiigoEverNoteFriendFeedMyspaceLinkedInMixxNetLogNetvibesPhonefavsPing.fmPlaxoDeliciousMister WongStumbleuponPlurkFunpMyshareFwisp
这是什么工具?
 JiaThis
         详解值类型与引用类型 结合ref  (利用案例一步步分析内存的变化)  

储存数组其实不是对象,而是对象的引用地址(储存对象的计算机的内存地址)
值类型,当方法调用的时候,因为传递进 方法的值只是原变量的一个副本,所以改变了副本不会改变原变量。
引用类型,当方法调用的时候,因为传递进方法的也是一个副本,只不过是 引用的副本,这个引用的副本也是指向 原对象的,所以修改了引用副本就会影响到对象。

如果结合这个案例,彻底把这个过程分析清楚:
分析案例:

复制代码
class Program    {        static void Main(string[] args)        {            int[] ints = { 1, 2, 3 };            int[] intsCopy = ints;//复制数组,使变量引用内存中相同的数组对象            Change(ints);//调用方法,传入引用            //ints :2 4 6            //intsCopy:2 4 6            int[] ints_second = { 1, 2, 3 };            int[] ints_secondCopy = ints_second;            ChangeAndRef(ref ints_second);//注意ref传入方法的引用是哪一个,那么 该引用就指向方法体内的新对象。            //ints_second:11 12 13            //ints_secondCopy:2 4 6        }        static void Change(int[] array)        {            for (int i = 0; i < array.Length; i++)            {                array[i] *= 2;            }            array = new int[] { 11, 12, 13 };        }        static void ChangeAndRef(ref int[] array)        {            for (int i = 0; i < array.Length; i++)            {                array[i] *= 2;            }            array = new int[] { 11, 12, 13 };        }
复制代码


第一步:int[] ints;这个是声明一个引用变量,这个时候不开辟内存
第二步:给数组初始化或者赋值,就会开辟内存,这里的开辟内存是值 用引用变量---指向--内存的地址--这个地址上有 一个对象(对象是占用内存的)
第三步:int[] intsCopy=ints;这是 声明一个 引用变量,让这个变量也---指向--内存中的地址---对象
第四步:调用方法,这个时候注意了,引用类型是把引用变量的副本信息,传递进方法里,这个引用变量的副本---对应---对象
第五步:因为引用副本所对应的地址也是内存中的对象,所以会修改对象,因此 原引用变量---对应内存中地址的对象(改变)
第六步:因为在方法体内 new 了一个新对象,就是开辟了一个新内存,那么方法体的引用变量是可以 指向这块内存的地址的,但是方法体外部的引用对象是无法指向这个方法体内的对象的,所以我们看到 方法1新 new int[] 未能改变引用变量--对应的对象

核心:

第二个方法体:利用ref 使得 引用了引用变量,也就是说修改了引用变量指向的对象。所以array=new int[],改变了原来的ints_second的引用--对象,但是并未修改ints_secondCopy的引用变量---所对应的对象。这个方法体:1.改变了原Ints_second的对象  2.在方法体内new一块新内存,让ints_second 指向了这块新内存上的对象

 

值类型:
案例1:(void情况)

复制代码
class Program    {        static void Main(string[] args)        {            int i = 5;//这里是Int类型所以是值类型            Console.WriteLine("The current i is {0}",i);//5            Change(i);            Console.WriteLine("The now i is {0}",i);//5 ,这里可以看出值类型不会改变原变量的值        }        static void Change(int i)        {            i *= 2;            Console.WriteLine("The i is {0}",i);//10        }    }
复制代码


 如果使用ref参数的话,那么方法体传递的就是对i的引用,那么就是会修改原i所对应的值的。


案例2:(有返回值的情况)

复制代码
 class Program    {        static void Main(string[] args)        {            int i = 5;//这里是Int类型所以是值类型            Console.WriteLine("The current i is {0}", i);//5            int new_i=Change(i);            Console.WriteLine("The now i is {0}", i);//5 ,这里可以看出值类型不会改变原变量的值            Console.WriteLine("The new_i is {0}",new_i);//10,这里可以看出值类型的是把副本的值改变了,其实并没有改变原变量的值        }        static int Change(int i)        {            i *= 2;            Console.WriteLine("The i is {0}", i);//10            return i;        }    
}

 

引用类型:
案例3:(void情况)

class Program    {        static void Main(string[] args)        {            int[] ints = { 1, 2, 3, 4, 5 };            Console.WriteLine("Lengths is {0}", ints.Length);//5            Console.WriteLine("The current ints is:");            foreach (int i in ints)            {                Console.Write(i + "");  // 1 2 3 4 5            }            int[] intsCopy = ints;//复制一份给intsCopy            Console.WriteLine();            ChangeArray(ints);            Console.WriteLine("The Now ints is:"); // 2 4 6 8 10,这里不一样了,变量引用的对象改变了!!            foreach (int i in ints)            {                Console.Write(i + "");            }            Console.WriteLine("The Now intsCopy is :");            foreach (int i in intsCopy)            {                Console.Write(i + "");//2 4 6 8 10 ,注意!!这里是原变量的复制版本居然也改变了,说明引用类型被方法调用修改是修改原变量的。            }        }        static void ChangeArray(int[] array)        {            for (int i = 0; i < array.Length; i++)            {                array[i] = array[i] * 2;            }        }    }
复制代码

 

案例4:(有返回值)

复制代码
class Program    {        static void Main(string[] args)        {            int[] ints = { 1, 2, 3, 4, 5 };            Console.WriteLine("Lengths is {0}", ints.Length);//5            Console.WriteLine("The current ints is:");            foreach (int i in ints)            {                Console.Write(i + "");  // 1 2 3 4 5            }            Console.WriteLine();            int[] intsCopy = ints;//复制一份给intsCopy            int[] new_ints = ChangeArray(ints);            Console.WriteLine("The new_ints is:");            foreach (int i in new_ints)            {                Console.Write(i + "");//2 4 6 8 10            }            Console.WriteLine();            ChangeArray(ints);            Console.WriteLine("The Now ints is:"); // 4 8 12 16 20            foreach (int i in ints)            {                Console.Write(i + "");            }            Console.WriteLine();            Console.WriteLine("The Now intsCopy is :");            foreach (int i in intsCopy)            {                Console.Write(i + "");//4 8 12 16 20            }        }        static int[] ChangeArray(int[] array)//定义方法修改数组        {            for (int i = 0; i < array.Length; i++)            {                array[i] = array[i] * 2;            }            return array;        }    }运行结果:Lengths is 5The current ints is:1  2  3  4  5The new_ints is:2  4  6  8  10The Now ints is:4  8  12  16  20The Now intsCopy is :4  8  12  16  20
0 0
原创粉丝点击