请问各位专业人士!1、定义一个类,该类中包括一个值类型的数组数据,譬如float[,] _data = new float[1000,1000],该属性在定义就进行了实例化;如下:
public class TestClass
    {
        float[,] _data = new float[500, 500];
        public TestClass()
        {
        }
        public float[,] Data
        {
            get { return _data; }
            set { _data = value; }
        }
    }
2、实例化该类。
_testClass = new TestClass();
3、在外部,创建一个相同类型的值类型数组;float[,] _newData = new float[5000,5000]; 并将该值赋值给实例化的类;
float[,] _data = new float[1000, 1000];
_testClass.Data = _data;问题是:
这时候的内存占用是一份还是两份呢?如果是一份的话,实例化时所分配的内存是在什么回收掉的?

解决方案 »

  1.   

    严格来说,你程序正在使用的是一份,还有一份等待GC回收。这仍是个关于引用类型及类的实例化的问题,CSDN曾经很多此类帖子,不妨搜搜看。
      

  2.   

    一份。。

    _testClass.Data = _data
    以后,GC会发现
    原来的_testClass.Data没人要了。
    所以回收
      

  3.   

    但是,我写了个测试的代码,发现还是一直有两份的,不知是什么原因。而且在赋值之后再回收,结果也貌似存在两份的。using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Diagnostics;namespace MemoryTest
    {
        public partial class Form1 : Form
        {
            PerformanceCounter _mem;
            TestClass _testClass;
            StringBuilder _sb = new StringBuilder(3 * 1024); //预先开辟一份内存,
            public Form1()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                _testClass = new TestClass();
                GC.Collect(GC.MaxGeneration);
                WriteLine("Class is created.");
            }        private void button2_Click(object sender, EventArgs e)
            {
                if (_mem == null)
                {
                    string _instanceName = System.Reflection.Assembly.GetEntryAssembly().GetName(false).Name;
                    if (PerformanceCounterCategory.Exists("Process") &&
                              PerformanceCounterCategory.CounterExists("Working Set", "Process") &&
                              PerformanceCounterCategory.InstanceExists(_instanceName, "Process"))
                    {
                        _mem = new PerformanceCounter("Process", "Working Set", _instanceName);
                    }
                }
                if (_mem != null)
                {
                    WriteLine("HashCode:{0} Memory:{1}Kb", _testClass != null ? _testClass.GetHashCode() : 0, _mem.NextValue() / 1024);
                }
            }        private void button3_Click(object sender, EventArgs e)
            {
                if (_testClass != null)
                {
                    float[,] _data = new float[5000, 5000];
                    _testClass.Data = _data;
                    GC.Collect(GC.MaxGeneration);
                    WriteLine("Class's attribute is set value.");
                }
            }        void WriteLine(string format, params object[] args)
            {
                _sb.AppendFormat(format, args);
                _sb.AppendLine();
                //string _message = format;
                //if (args != null)
                //    _message = string.Format(format, args);
                //richTextBox1.AppendText(_message);
                //richTextBox1.AppendText(Environment.NewLine);
                //richTextBox1.ScrollToCaret();            //Console.WriteLine(format, args);
            }        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                Console.WriteLine(_sb.ToString());
            }
        }
        public class TestClass
        {
            float[,] _data = new float[500, 500];
            public TestClass()
            {
            }
            public float[,] Data
            {
                get { return _data; }
                set { _data = value; }
            }
        }
    }
      

  4.   

    在你实例化float[,] _newData = new float[5000,5000]; 
    的时候,内存里面是两份。当你把这一份赋值给_testClass.Data = _data;
    后内存里只有一份,其中一份已被回收,属性和外部的数组都指向一个内存空间
      

  5.   

    测试用例稍改,是一份.private void button1_Click(object sender, EventArgs e)
    {
        float[,] _data外 = new float[1000, 1000];
        TestClass _testClass = new TestClass();
        _testClass.Data = _data外;
        
        _data外[0, 0] = 100;    GC.Collect(0);
        ;
    }
    public class TestClass
    {
        public float[,] _data = new float[500, 500];
        public TestClass()
        {
        }
        public float[,] Data
        {
            get { return _data; }
            set { _data = value; }
        }
    }
      

  6.   

    我还是想看看,有没有MVP之类的专家出来说说话,请各位稍等哈。
      

  7.   

    _data 是类的字段,当你new 一个新的实例的时候,字段肯定是首先被实例化的,所以当执行_testClass = new TestClass();的时候先在托管堆中开辟了内存空间,我们先将它称为块A,,然后执行float[,] _data = new float[1000, 1000];的时候再在托管堆中开辟了内存空间,称为块B,这里面的值由局部变量_data这个引用所维持。执行_testClass.Data = _data;的时候,_testClass中的字段_data和局部变量_data变成了同一个引用的不同副本,也就是都指向块B。此时块A没有了引用指向它,所以不久将会被GC回收,但具体时间不能确定。
    所以_testClass.Data = _data;执行完后,内存中还存在块A和块B,块A何时被GC回收,由GC确定
      

  8.   

    而且补充说一句,虽然float是值类型,但float[,]是引用类型的
    所有的数组都是引用类型