1

I have a fairly simple single-threaded program C#/WPF program. It has a few buttons and a canvas; it loads a file and displays some graphics. It's got some arrays of doubles and bools totalling about 1G, and until now it's worked fine. It does not explicitly do any interop nor explicitly reference any COM objects, but I have no idea what the framework is doing behind the scenes. It's built for AnyCPU and running on an x64 system

I added a ListBox and now when I run it I get a COM error . . .

An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll Additional information: Not enough storage is available to process this command. (Exception from HRESULT: 0x80070008)

Stepping in the debugger the error appears to happen AFTER it executes the main window constructor, where all the array space is allocated, when it's first displaying the UI. Literally I can breakpoint on the closing curly-brace of the c'tor but if I F11 from there it blows up.

The Resource binding in the XAML:

<!-- Resource for the plylist -->
<Window.Resources>
    <ObjectDataProvider x:Key="plies" ObjectType="{x:Type local:Plies}"/>
    <DataTemplate x:Key="ThePlies" DataType="Partition1.MyPly">
        <StackPanel >
            <TextBlock Text="{Binding Path=PlyName}" FontFamily="Arial" 
                       FontSize="18"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

The ListBox in the XAML ...

<ListBox BorderBrush="DarkGray" Width="200" Height="300" BorderThickness="3" Margin="10,100,0,0"
         Padding="0" Background="White"   HorizontalAlignment="Left"  VerticalAlignment="Top"
         ItemsSource="{Binding Source={StaticResource plies}}"
         ItemTemplate="{StaticResource ThePlies}"/>

The C# looks like this . . .

public class MyPly
{
    public string PlyName { get; set; }
    public MyPly(string plyName)
    {
        this.PlyName = plyName;
    }
}


public class Plies : List<MyPly>
{
    public Plies()
    {
        this.Add(new MyPly("PLY ONE"));
        this.Add(new MyPly("PLY TWO"));
        this.Add(new MyPly("PLY THREE"));
        this.Add(new MyPly("PLY FOUR"));
        this.Add(new MyPly("PLY FIVE"));
        this.Add(new MyPly("PLY SIX"));
        this.Add(new MyPly("PLY SEVEN"));
        this.Add(new MyPly("PLY EIGHT"));
        this.Add(new MyPly("PLY NINE"));
    }
} 

How do I figure out what's causing this, and what's using up my storage?


Solved

- I found the cause - I found the actual problem and it involved another SO post related to this project (which as of this writing has received 0 comments or answers) https://stackoverflow.com/questions/35464287/xaml-errors-only-in-x64. Since I couldn't build for x64 with this XAML I set my build for AnyCPU. I'm on a 64 bit machine, running a 64 bit version of Win7 so AnyCPU should just JIT to 64 bits, right?

Wrong. Because Visual Studio has a little-known checkbox in the Project properties, build setting called "Prefer 32-bit" which basically overrides your 64 bit expectations. So I actually WAS running out of memory in the constructor but I didn't know it. When I went into Debug Exceptions and enabled "Common Language Runtime" exceptions THEN I got the crash during initialization, while it was still doing construction.

I unchecked the "Prefer 32-bit" and my COM error vanished.

Community
  • 1
  • 1
user316117
  • 7,971
  • 20
  • 83
  • 158
  • 1
    How much memory does the machine has available? – Stefan Feb 17 '16 at 20:56
  • 8G. Before I run this program the OS and other programs are consuming about 3G. When I run this program and it allocates all its arrays the total being used by the OS, all the other programs **plus** this program is about 4G. – user316117 Feb 17 '16 at 20:59
  • 1
    Do you have an single object which is larger than 2 GB in memory? – Stefan Feb 17 '16 at 21:10
  • Nope. Just a 16000 element array of objects consisting of a handful of doubles and bools. They're initialized in a 'for' loop in the main constructor. And as I said it gets through that constructor where this stuff is allocated BEFORE the blow up happens. if I breakpoint before exiting the c'tor I can see in Task Manager that the system has allocated all that memory. – user316117 Feb 17 '16 at 21:15
  • 1
    As far as I can tell the code looks okay. You could try to remove the listbox again or delay-fill it through a button. The strange thing is that I only saw this error on faulty-mem/harddisk systems and excessive use of system resources as described here: http://stackoverflow.com/questions/548971/win32exception-not-enough-storage-is-available-to-process-this-command#549025 – Stefan Feb 17 '16 at 21:26
  • 1
    A stack trace is pretty important to get an explanation, preferably one that is generated by enabling unmanaged debugging. It is a Windows error, error code 8. Do make sure you don't confuse WPF with WinRT, they look kinda similar but are very different under the hood. If it is WPF then the most likely underlying reason is a problem with the kernel memory pool or a hiccup in the video driver. Reboot the machine and try again. – Hans Passant Feb 17 '16 at 22:33
  • I found the problem - see the edit. I +1'ed everybody who participated for their effort. Thanks, but it was my bad. – user316117 Feb 18 '16 at 14:47

1 Answers1

2

If the error only started after you added the ListBox then the problem is most likely because the UI is trying to load all the items in the array into the ListBox at one time. This will cause a crash on some systems or very long delays on others.

Try setting this property on your ListBox in XAML:

VirtualizingPanel.IsVirtualizing="True"

Stewbob
  • 16,759
  • 9
  • 63
  • 107
  • I found the problem - see the edit. I +1'ed everybody who participated for their effort. Thanks, but it was my bad. – user316117 Feb 18 '16 at 14:44