【问题标题】:Releasing memory blocks from objects in static methods inside a non-static class c#从非静态类c#中的静态方法中的对象释放内存块
【发布时间】:2021-06-30 14:42:30
【问题描述】:

我在非静态类中使用静态方法,每次调用该静态方法时,都会创建一个对象的新实例

       public  class BaseMethodsExecuter<T> where T:class
        {
            public static T Execute(BaseMethodsParams input, BaseBusinessEnum businessEnum) 
            {
                T data=null; 
                try
                {
                  data = ExecuteMethod(input, businessEnum);
                }
                catch (Exception ex)
                {
    
                }
                return data;
            }
            private static T ExecuteMethod(BaseMethodsParams input, BaseBusinessEnum businessEnum)
            {
              // this is the line that fell me to thinking 
                var TypeMethod = typeof(BaseDataAbstract<T>).Assembly.GetTypes().Single(t => t.BaseType==(typeof(BaseDataAbstract<T>)) && !t.IsAbstract && ((BaseDataAbstract<T>)Activator.CreateInstance(t)).BaseBusinessMethod== businessEnum);
                var BaseMethod=(BaseDataAbstract<T>)Activator.CreateInstance(TypeMethod);
                var data=BaseMethod.GetBaseData(input);
                return data;
            }
        }

以下代码在静态方法中创建对象

((BaseDataAbstract<T>)Activator.CreateInstance(t))

据我所知,Static objects 将其内存块保存在 stack 部分内存中。 是不是意味着每次调用这个方法都会有一个额外的空间被实例化对象占用,再也不会被释放了?

如何从内存中清除静态方法中的对象?

【问题讨论】:

  • 你的代码中没有静态对象,只有静态方法。它们都只是普通的类对象(甚至不是结构),将在堆上分配。确实,它们上的标准机器大小字引用将在堆栈上,但一旦您不需要它们就会被释放。
  • As far as i know, Static objects hold their memory blocks in stack part of the memory.你是怎么得出这个结论的?
  • 一个方法是否是静态的对该函数内部声明/实例化的对象的行为没有有意义的影响。静态方法中的对象将像非静态方法中的对象一样被清理。
  • 把对对象的引用想象成一根绳子。在您的情况下,绳索称为data,您将绳索返回给调用者。呼叫者现在抓住绳子,绳子连接到对象。同一个物体可能附有多条绳索。直到所有绳索都被分离,该对象将在内存中。如果系上绳索并且您处置了该物体,那么拥有绳索并试图使用该物体的人将获得例外。所以即使你离开了方法,仍然需要到对象的绳索所以对象仍然存在并且需要存在,否则为什么要返回它。
  • 改变的是绳子的名称。在此方法中,它被称为data,当方法离开时,名称data 将被丢弃,因此堆栈内存被清除。调用者可以使用新名称或不使用新名称调用data,但该名称将存在于该堆栈中,依此类推。

标签: c# memory stack static-methods


【解决方案1】:

首先: 引用对象存储在堆中。指向该对象的所有引用指针都存储在堆栈中。 当堆栈中没有更多指针时,从堆中删除对象(参见垃圾收集器)。

话虽如此: 静态对象是堆中指向堆栈中对象的静态引用指针,因此该对象永远不会被释放。 在您的示例中,(((BaseDataAbstract&lt;T&gt;)Activator.CreateInstance(t)).BaseBusinessMethod== businessEnum); 创建了一个实例,但该实例未分配给静态变量。 var BaseMethod=(BaseDataAbstract&lt;T&gt;)Activator.CreateInstance(TypeMethod); 也一样,它们被分配给ExecuteMethod 内的一个作用域变量。 一旦我们跳出方法,这些变量(栈)就消失了,堆中的引用对象在GC处理它们的时候也消失了。

【讨论】:

  • They will exist in the heap until disposed @CodingYoshi Disposing 会导致它们从堆中移除吗?你有什么引文可以让我进一步阅读吗?
  • 这个粗体部分不正确或不正确:“一旦我们跳出方法,这些变量(堆栈)就会消失,堆中的引用对象也会消失。” 他们将存在于堆中,直到被处理(直到 GC 将它们删除为迂腐)或应用程序关闭。
  • @CodingYoshi 是的,它们因为 GC 而消失了,我没有重复这一点,因为它已经在解释的第一部分中。我已经编辑了我的回复以再次提及它。
猜你喜欢
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 2013-02-07
  • 1970-01-01
  • 2015-02-18
  • 1970-01-01
  • 2014-11-30
  • 1970-01-01
相关资源
最近更新 更多