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中关于托管指针的规则:“托管指针不能存储在静态变量、数组元素或对象或值类型的字段中”。这让垃圾收集器的生活变得简单多了。