Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.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# 为什么GC堆上的托管指针会使JIT编译器崩溃?_C#_.net_Visual Studio_Garbage Collection_Clr - Fatal编程技术网

C# 为什么GC堆上的托管指针会使JIT编译器崩溃?

C# 为什么GC堆上的托管指针会使JIT编译器崩溃?,c#,.net,visual-studio,garbage-collection,clr,C#,.net,Visual Studio,Garbage Collection,Clr,我一直在阅读,我不确定我是否理解了关于ref-struct声明一节中特定部分的含义。 这是: […]此外,将托管指针放在GC堆上通常会在JIT时崩溃 这到底是什么意思?假设我有这样的东西: IntPtr ptr = Marshal.AllocHGlobal(sizeof(float) * 100); float* pt = (float*)ptr.ToPointer(); Parallel.For(0, 10, i => { for (int j = 0; j < 10;

我一直在阅读,我不确定我是否理解了关于
ref-struct
声明一节中特定部分的含义。 这是:

[…]此外,将托管指针放在GC堆上通常会在JIT时崩溃

这到底是什么意思?假设我有这样的东西:

IntPtr ptr = Marshal.AllocHGlobal(sizeof(float) * 100);
float* pt = (float*)ptr.ToPointer();
Parallel.For(0, 10, i => 
{ 
    for (int j = 0; j < 10; j++) pt[i * 10 + j] = i * 10 + j;
});
IntPtr ptr=Marshal.AllocHGlobal(sizeof(float)*100);
float*pt=(float*)ptr.ToPointer();
对于(0,10,i=>
{ 
对于(intj=0;j<10;j++)pt[i*10+j]=i*10+j;
});
或者另一个例子:

float[,] m = new float[10, 10];
fixed (float* pt = m) // I know I could put this inside the lambda, but this
{                     // way the pointer should be captured by the closure
                      // and therefore end up on the GC heap
    Parallel.For(0, 10, i => 
    { 
        for (int j = 0; j < 10; j++) pt[i * 10 + j] = i * 10 + j;
    });
}
float[,]m=新的float[10,10];
修正(float*pt=m)//我知道我可以把这个放在lambda中,但是这个
{//闭包捕获指针的方式
//并因此在GC堆上结束
对于(0,10,i=>
{ 
对于(intj=0;j<10;j++)pt[i*10+j]=i*10+j;
});
}
我假设在这两种情况下,
float*
指针将被捕获并存储在GC堆上,在闭包内,因此:

  • 这两种情况中的一种(或两者)会导致问题吗
  • 这是那一段所说的,还是另一种情况
  • 如果是这种情况,为什么这样的事情会导致JIT编译器崩溃

谢谢

您在示例中拥有的不是托管指针。例如,托管指针是“ref something”参数。“crash”是由内置在jitter中的验证器产生的。它强制执行Ecma-335第二章14.4.2中关于托管指针的规则:“托管指针不能存储在静态变量、数组元素或对象或值类型的字段中”。这让垃圾收集器的生活变得简单多了。