问题
I have a small read-only database (based on data from services). The load time is critical so data can't be extracted from DB, XML and so on. I use the direct construction of data in the generated C# file:
void Load(){
var aa = new A[ 100500 ];
aa[0] = new A( ... );
...
aa[100499] = new A( ... );
AA = aa;
}
There are no recursion here, stackallocks and so on. But I have got a StackOverflow error.
Looking in Disassembler window I found that JIT converts this code into:
var aa = new A[ 100500 ];
var a0 = new A( ... );
aa[0] = a0;
...
var a100499 = new A( ... );
aa[100499] = a100499;
So it create 100500 variables aXXXXX in stack:
-- aa[32] = new A( qwerty, asdf );
mov ecx,185C10h -- var a32 = new A
call 001730F4
mov dword ptr [ebp-4Ch],eax -- different for different rows
push dword ptr ds:[4403528h] -- a32.ctor( ... )
mov edx,dword ptr ds:[4403524h]
mov ecx,dword ptr [ebp-4Ch]
call 00790068
push dword ptr [ebp-4Ch] -- aa[32] = a32
mov ecx,dword ptr [ebp-3Ch]
mov edx,20h
call 71CCCD30
These changes doesn't help:
// 1. explicit variable
A a;
a = new A( ... ); // a32 = new A(...); a = a32;
aa[32] = a
// 2. limited visibility
{ aa[32] = new A( ... ); } // for each created object
This change helps but too ugly:
// Works in Release version only
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void f32( A[] aa )
=> aa[32] = new A( qwerty, asdf );
...
f32( aa ); -- inlined without a32
Is any elegant way to remove these stack devourers?
Thanks in advance.
来源:https://stackoverflow.com/questions/59528181/why-am-i-getting-a-stackoverflow-error-in-a-long-method