zoukankan      html  css  js  c++  java
  • 值类型与引用类型初窥

    没有时间写废话,直接上测试代码。

        class TestAddressRef

        {

            public int num;

        }

    class Program

        {

            static void Main(string[] args)

            {

                TestAddressRef tar1=new TestAddressRef();

                tar1.num = 1;

                TestAddressRef tar2 = tar1;

                TestAddressRef tar3=new TestAddressRef();

                TestAddressRef tar4 = tar3;

                tar3.num = 3;

                tar3 = tar1;

                Console.WriteLine("tar1的值{0}/ntar2的值{1}/ntar3的值{2}/ntar4的值{3}/n", tar1.num, tar2.num, tar3.num,tar4.num);

            }

    输出为:

    tar1的值1

    tar2的值1

    tar3的值1

    tar4的值3

    我是这样理解的:

    new 一个对像后,在堆内分配一个该对象的存储空间。在栈内为该标志符赋值为 堆内该对象的首地址,并记录对象类型(空间什么的)。

    如这句话TestAddressRef tar1=new TestAddressRef();

    而对于TestAddressRef tar2;相当于仅在栈内分配了一个空间,保存实际对象的地址为null(即该对象未在队内分配空间)。当有 tar2 = tar1时,将tar1栈内的值给了tar2,这样,tar2也指向了与1相同的堆内对象。

    3 和4 就比较有意思了,3申请了新空间后,4也得到这个地址,然后3栈内保存的地址又被1赋值,即3有指向了1所指向的堆空间,也就是放弃了原来申请的堆空间的控制(4控制着该堆内的对象,4这里起到了捕获3遗漏空间的作用)。就出现了如上结果。

    我有个疑问,当tar3 放弃了对原堆空间的控制后,转向1,会不会产生内存泄露了呢(不用4捕获的情况下)???

    因为编译器无法获知原来tar3申请的空间什么时候会失效(其实,如果不是我们用tar4来捕获,到最后tar4超出了它的作用域,连我们自己也不知道该空间内保存的值什么时候才会不被用到),编译器貌似就难以在适时的时候进行垃圾回收了!????我暂时还没想明白,应该牵涉到垃圾回收的机制吧,等我想明白了再来补上。

    恩,就这样。

    欢迎提出不同的观点。

    ###


    补1:

         (1) 不是所有new一下就是引用类型,如struct类型。

                 定义个结构类型Mystruct, 如果写Mystruct ms=new Mystruct();结构实例对象仍然是在栈内分配的。new一下,编译器会认为实例已初始化。如果没有new,认为实例的所有字段没有初始化,不可访问使用,编译错误。

    #####2011-10-12

    或许我们根本不用担心这个问题,C#垃圾回收应该就是干这个事的。至于什么时候才回收,现在暂时还不是很清楚。

  • 相关阅读:
    Java实现线程的三种方法
    java 包和访问权限小结
    Java从外部调用类的私有方法
    find
    sigprocmask
    alerm和pause
    kill和raise
    信号处理中可重入函数调用
    低速系统调用的信号中断
    signal函数
  • 原文地址:https://www.cnblogs.com/linecheng/p/2210976.html
Copyright © 2011-2022 走看看