放置物体时出现问题

问题描述:

大家好,

我在摆放物体时遇到问题.我创建了用于处理对象的演示应用程序.当应用程序执行时,它占用约5 mb的空间,一旦我单击按钮,内存使用量就会增加到40 mb.如果我单击内存使用次数的增加,我将采取所有措施在使用后处置该对象. br/>
我将我的代码放在下面.


Hi All,

I am facing a problem to dispose a object. I created demo application for disposing object. when application is executing it is taking around 5 mb,once i click on button memory usage is raising upto 40mb.If i am clicking number of times memory is usage is increasing.I have taken all the measures to dispose the object after using.

i am putting my code below.


private void button_Click(object sender, EventArgs e)
        {
            using (DataTable dt = new DataTable())
            {
                dt.Columns.Add("Name", typeof(string));
                using (CheckingPerformance objCheckingPerformance = new CheckingPerformance())
                {
                 objCheckingPerformance.method(objCheckingPerformance.method_row(dt));

                }
            }
        }







public class CheckingPerformance:IDisposable
    {
        public DataTable dt = null;
        public DataRow dr = null;
        private bool _disposed;

        public DataTable method(DataTable pdt)
        {
            return pdt;
            
        }

        public DataTable method_row(DataTable dt)
        {
            
                for (int i = 0; i <= 200000; i++)
                {

                    dt.Rows.Add("admin" + i.ToString());
                }
                return dt;
            
        }

            

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // Dispose managed resources
                    //if (_stream != null) _stream.Dispose();
                    if (dt != null) dt = null;
                    if (dr != null) dr = null;
                }
 
                // Dispose unmanaged resources
                //_handle = IntPtr.Zero;
 
                //_stream = null;
                _disposed = true;
            }
        }
 
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~CheckingPerformance()
        {
            Dispose(false);
        }

    }




请让我知道我在哪里做错.




Please let me know where i am doing mistake.

那是问题所在.您认为错误是一种行为.
如果要强制垃圾收集(用于测试),请使用GC.Collect().如果即使内存不断增加,那么您的问题也与处置无关,而与拥有不可收集的对象有关(如果您仍有保存对象的变量).
但是除非您出于测试目的或您非常确定需要使用它,否则不应调用GC.Collect.

实际上,我可以向您展示此示例:
想象一下,您以独占模式打开了数千个文件,并将它们放入列表中.
如果清除列表而不处理对象,则这些文件仍将打开,并在下一个垃圾回收时关闭(默认情况下,您不知道何时会发生这些文件).
如果您在不清除列表的情况下处理所有文件,则文件将被关闭(并且可以被其他程序读取/写入),但用于表示它们的托管内存仍将被分配(即使垃圾收集已完成).
如果您:清除列表,然后调用GC.Collect(无论是否进行处理,都将独立调用),那么所有文件将被关闭并且其内存将被回收.

实际上,Dispose仅允许您立即关闭它们,而不会强制进行垃圾回收(因为手动调用垃圾回收会导致很多与新回收有关的问题).

因此,要进行测试:如果调用GC.Collect,则应恢复内存.而且,即使使用GC.Collect,也有可能从不释放某些mb,这并不是.NET管理其内存使用情况的错误.那些从未解除分配的内存块将保留给新分配.
That''s the problem. What you consider an error is a behavior.
If you want to force garbage collection (for tests) use GC.Collect(). If even with that the memory keeps increasing, then your problem is not related to dispose, but to having non-collectible objects (if you still have variables holding the objects).
But you should not call GC.Collect unless it is for tests purposes or if you are pretty sure it is needed.

In fact, I can show this example to you:
Imagine that you open thousands of files in exclusive mode and puts them into a list.
If you clear the list without disposing the objects, those files will still be opened, and will be closed at the next Garbage Collection (with by default you don''t know when it will happen).
If you Dispose all of the files without clearing the list, then the files will be closed (and can be read/written by other programs) but the managed memory used to represent them will still be allocated (and will not be deallocated even if a garbage collection is done).
If you: Clear the list and then call GC.Collect (independently if you dispose before or not) then all the files will be closed and their memory will be reclaimed.

The Dispose, in fact, only allow you to close them immediately, without forcing a garbage collection (as calling the Garbage Collection manually causes a lot of problems regarding to new collections).

So, to test: If you call GC.Collect, the memory should be recovered. And, even with GC.Collect it is possible that some mb are never deallocated, and this is not a bug, is how the .Net manages its memory useage. Those never deallocated memory blocks are reserved to new allocations.


我不知道您如何进行测试...但是即使在处理对象时,某些资源(对象本身)保留在内存中,直到GC决定收集它们为止.
Dispose的真正目的是避免使非托管资源处于活动状态的时间超过所需的时间(例如,立即关闭数据库连接),但是用于表示该集合的.Net类的内存将不会立即被回收. br/> 就DataTable而言,所有数据表行仍将保留在内存中,直到垃圾回收器决定运行为止.
I don''t know how you are doing your tests... but even when disposing objects, some resources (the memory fot the objects themselves) are kept in memory until the GC decides to collect them.
What Dispose really does is to avoid unmanaged resources to be kept active for more time than needed (for example, a database connection is closed immediately), but the memory used for the .Net class that represents the collection will not be immediately reclaimed.
In the case of the DataTable, all datatable rows will still be in memory until the garbage collector decides to run.