static constructors in compact framework - size limit?

If anyone has seen this before, I would appreciate some advice or a workaround. I'm trying to use a static constructor in a class using several jagged arrays. I can add a few of them, and it works okay, but after a certain limit, the application either throws a "System.NotSupportedException" or a fatal application error 0xC00000005. I haven't found anything on the web, and the application runs fine on the desktop. I trimmed this down to make the jagged arrays readable, but it looks like a textbook example of static constructors.

public class MainClass
{
static void Main()
{
huffcodetab.inithuff();
}

}
public class huffcodetab
{
private static int[][] ValTab0;
private static int[][] ValTab1;

public static void inithuff()
{
Console.WriteLine("huffcodetab.inithuff called");
}
static huffcodetab()
{
ValTab0 = new int[][] {new int[]{12, 1},
// add more of "new int[][]{x,y}" values
new int[]{4, 1}, new int[]{0, 119}};
ValTab1 = new int[][] {new int[]{12, 1},
// add more of "new int[][]{x,y}" values
new int[]{4, 1}, new int[]{0, 119}};

}
}






Answer this question

static constructors in compact framework - size limit?

  • ekb0211

    It took some time to get this one going, but I found a solution. It was the 64k limit of JITted code that I exceeded. I thought is was some size limt in the constructor (and I still may have this slightly off), but apparently, you can't have any instruction over 64k, not in the constructor, methods - anywhere, or it will blow up with the System.NotSupportedException, or OutOfMemory, or TypeLoadException. I got different exception whether the code was running in an emulator or on a device. So to load up the big jagged array in the static constructor, I split the array into two. I put them both in methods that return the partial array, then copy them together with the Array.Copy. If there are better ways to do this, please post one (I'd be interested to see it), but the following is what I did:

    public class huffcodetab
    {

    private static int[][] ValTab15;

    static huffcodetab()
    {
    ValTab15 = new int[ReturnValTab15_part1().GetLength(0) +
    ReturnValTab15_part2().GetLength(0)][];
    Array.Copy(ReturnValTab15_part1(),0,ValTab15,0,
    ReturnValTab15_part1().GetLength(0));
    Array.Copy(ReturnValTab15_part2(),0,ValTab15,
    ReturnValTab15_part1().GetLength(0),ReturnValTab15_part2().GetLength(0));
    }

    private static int[][] ReturnValTab15_part1()
    {
    return new int[][]
    {
    new int[]{2, 1}, new int[]{0, 0},
    //the rest of the oversize array
    new int[]{2, 1}, new int[]{0, 0}
    };
    }

    private static int[][] ReturnValTab15_part2()
    {
    return new int[][]
    {
    new int[]{2, 1}, new int[]{0, 0},
    //the rest of the oversize array
    new int[]{2, 1}, new int[]{0, 0}
    };
    }

    }


  • wBob

    Thanks Ilya and Alex,

    I've made some progress with this thanks to your link. I've testing this with a CE.NET 4.2 device, as well as the CE and PPC emulator. I've changed the code to have several method calls in the static constructor. (I hope I have the terms right)

    static huffcodetab()
    {
    ValTab1 = ReturnValTab1(); //use a method this time
    ValTab2 = ReturnValTab2(); //etc
    }
    private static int[][] ReturnValTab1()
    {
    return new int[][] {new int[]{12, 1},
    // add more of "new int[][]{x,y}" values
    new int[]{4, 1}, new int[]{0, 119}};
    }

    And the code now works on the CE device, but still dies in the CE and PPC emaulators. They fail with a NotSupportedException, then a managed OutOfMemoryException. (two dialog boxes). It quits when I call the method that returns a int[517][2] sized array. The other arrays that work are all int[127][2]. Have I cross some magic line that works that won't work on the emulators On the CE device, the memory usage only goes from 6.3 MB to 7.4 MB. Is there any way that I could change the way the methods are called to make it more tolerant Thanks guys.


  • Ken Villines

    Thanks for the link. It looks like it's right on target. I'm a newbie at this, but I'm trying to keep up. I'll have to look up "jitted code", but one person responded with "You could even, potentially, break the
    instantiation of your array into several functions." I tried the following (moving the instantiation of the array into a function), but the results were the same.

    The link also mentioned putting all the data in an embedded resource, then reading it in (I assume in the constructor). I can't see how that would be any different - the method that returns the array would just have read, populate and return the array Wouldn't the "jitted code" be identical after the method returns. Anyway - thanks for the link. I'll keep searching. If you have advice, I would welcome it. - dan

    public class MainClass
    {
    static void Main()
    {
    huffcodetab.inithuff();
    }

    }
    public class huffcodetab
    {
    private static int[][] ValTab0;
    private static int[][] ValTab1;

    public static void inithuff()
    {
    Console.WriteLine("huffcodetab.inithuff called");
    }
    static huffcodetab()
    {
    ValTab1 = ReturnValTab1(); //use a method this time
    }
    private static int[][] ReturnValTab1()
    {
    return new int[][] {new int[]{12, 1},
    // add more of "new int[][]{x,y}" values
    new int[]{4, 1}, new int[]{0, 119}};
    }

    }


  • pingfr2005

    graymon wrote:


    The link also mentioned putting all the data in an embedded resource, then reading it in (I assume in the constructor). I can't see how that would be any different - the method that returns the array would just have read, populate and return the array Wouldn't the "jitted code" be identical after the method returns.

    No, it wouldn't. Static initialization results in all of the array initialization data becoming the part of the method's code blowing the size limit. Reading the data from an embedded resource does not have this problem



  • cisco0407

  • static constructors in compact framework - size limit?