Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# (如何)在Unity 2019上强制垃圾收集并等待挂起的终结器?_C#_Unit Testing_Unity3d_Garbage Collection - Fatal编程技术网

C# (如何)在Unity 2019上强制垃圾收集并等待挂起的终结器?

C# (如何)在Unity 2019上强制垃圾收集并等待挂起的终结器?,c#,unit-testing,unity3d,garbage-collection,C#,Unit Testing,Unity3d,Garbage Collection,我的团队正在C#进行一个联合项目。在某些地方,我们调用System.GC.Collect()和System.GC.WaitForPendingFinalizers()(仅在测试中,不在生产代码中。为什么这样做与我的问题无关,但如果有人感兴趣,请在下面解释)。这曾经在Unity 2018.1上运行良好,但自从我们升级到Unity 2019.1以来,似乎一直停止运行(即,它似乎有时运行,但并不总是)。我们在macOS上使用Mono,并尝试了新引入的增量GC功能,包括on和off,没有明显的区别 有人

我的团队正在C#进行一个联合项目。在某些地方,我们调用
System.GC.Collect()
System.GC.WaitForPendingFinalizers()
(仅在测试中,不在生产代码中。为什么这样做与我的问题无关,但如果有人感兴趣,请在下面解释)。这曾经在Unity 2018.1上运行良好,但自从我们升级到Unity 2019.1以来,似乎一直停止运行(即,它似乎有时运行,但并不总是)。我们在macOS上使用Mono,并尝试了新引入的增量GC功能,包括on和off,没有明显的区别

有人知道在统一版本之间有什么变化可以解释这一点吗?还有人知道其他强制垃圾收集并等待Unity 2019上的待定终结器的方法吗

我尝试过但没有成功的事情:多次调用
GC.Collect()
GC.WaitForPendingFinalizers()
,调用它们后长时间睡眠,分配大量内存(我猜不够大,但我也不想推它)

注意:我们依次调用
Collect()
WaitForPendingFinalizers()
;我不知道这两种方法中的哪一种实际上没有达到预期的效果(或者两者是否都是),因为只有两者结合起来才具有我们正在测试的可观察效果。有助于缩小问题范围的想法也将受到赞赏

我们为什么需要这个

我们有一个类,它的实例根据环境的不同可能是长期存在的,并且在其生命周期的某个时刻存储了大量的数据,这些数据在以后不再需要。为了允许释放内存,当不再需要数据时,引用它的字段被分配为
null

我没有理由相信这不能正常工作,但问题在于此功能的单元测试,它在Unity 2018.1上运行得很好,但自从我们将项目迁移到Unity 2019.1以来,一直间歇性地失败

示例代码

下面是一个(简化了很多!)的例子,说明了这个问题:该测试始终通过Unity 2018.1,但没有通过Unity 2019.1。我尽量把它减到最少。我不知道为什么,但如果不使用
列表
(一个类似的版本,其中有一个
对象
,而不是在Unity 2019.1上一致传递的
列表
),我就无法使它工作-这可能是问题的一部分,也可能不是问题的一部分

using System;
using System.Collections.Generic;

using NUnit.Framework;

public class MyClass {
    List<object> someData = new List<object>();

    public void RegisterData(object data) => someData.Add(data);

    public void ForgetData() => someData = null;
}

[TestFixture]
public class MyClassTest {
    class ObservablyFinalizable {
        readonly Action onFinalize;

        public ObservablyFinalizable(Action onFinalize) {
            this.onFinalize = onFinalize;
        }

        ~ObservablyFinalizable() {
            onFinalize();
        }
    }

    MyClass instance;
    bool isFinalized;

    [SetUp]
    public void SetUp() {
        instance = new MyClass();
        isFinalized = false;
    }

    [Test]
    public void ShouldForgetData() {
        WhenRegisteringObservablyFinalizableData();
        WhenForgettingData();
        WhenGarbageCollected();

        ThenFinalized();
    }

    void WhenRegisteringObservablyFinalizableData() =>
        instance.RegisterData(new ObservablyFinalizable(() => isFinalized = true));

    void WhenForgettingData() => instance.ForgetData();

    static void WhenGarbageCollected() {
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }

    void ThenFinalized() => Assert.That(isFinalized);
}
使用系统;
使用System.Collections.Generic;
使用NUnit.Framework;
公共类MyClass{
List someData=新列表();
public void RegisterData(对象数据)=>someData.Add(数据);
public void ForgetData()=>someData=null;
}
[测试夹具]
公共类MyClassTest{
类ObservalyFinalizable{
只读操作onFinalize;
公共可观察最终化(操作最终化){
this.onFinalize=onFinalize;
}
~ObserveryFinalizable(){
onFinalize();
}
}
MyClass实例;
布尔最终确定;
[设置]
公共作废设置(){
实例=新的MyClass();
isk=false;
}
[测试]
public void ShouldForgetData(){
在注册可观测最终化数据()时;
当定位数据()时;
当RBAGECollected()时;
然后确定();
}
注册可观测最终化数据()时无效=>
RegisterData(新的ObservalyFinalizable(()=>IsFinalizated=true));
void whenforgetingdata()=>instance.ForgetData();
收集RBAGECollected()时的静态无效{
GC.Collect();
GC.WaitForPendingFinalizers();
}
void ThenFinalized()=>Assert.That(isFinalized);
}

可能相关:谢谢,@derHugo。这似乎与我无关:这里的关注点似乎是性能,而我触发收集的原因根本不是性能:它是为了验证代码的正确行为,我只在测试中这样做(这似乎是可以接受的做法,请参见-神话:调用
GC.Collect()
会导致终结器运行,例如)。此外,我的问题是关于从Unity 2018.1到Unity 2019.1的过渡:给定的代码在前者上一致通过,但在后者上间歇性失败。可能相关:谢谢,@derHugo。这似乎与我无关:这里的关注点似乎是性能,而我触发收集的原因根本不是性能:它是为了验证代码的正确行为,我只在测试中这样做(这似乎是可以接受的做法,请参见-神话:调用
GC.Collect()
会导致终结器运行,例如)。此外,我的问题是关于从Unity 2018.1到Unity 2019.1的过渡:给定的代码在前者上一致通过,但在后者上间歇性失败。