【问题标题】:OutOfMemoryException On Mobile Device移动设备上的 OutOfMemoryException
【发布时间】:2010-10-10 06:52:38
【问题描述】:

我正在开发一个应用程序,它使用移动设备拍摄照片并使用网络服务发送。但是在我拍了 4 张照片之后,我在下面的代码中得到了一个 OutOfMemoryException。我试过打电话给GC.Collect(),但也没有用。也许这里有人可以给我一个建议如何处理这个问题。

public static Bitmap TakePicture()
{
    var dialog = new CameraCaptureDialog
    {
        Resolution = new Size(1600, 1200),
        StillQuality = CameraCaptureStillQuality.Default
    };

    dialog.ShowDialog();

    // If the filename is empty the user took no picture
    if (string.IsNullOrEmpty(dialog.FileName))
       return null;

    // (!) The OutOfMemoryException is thrown here (!)
    var bitmap = new Bitmap(dialog.FileName);

    File.Delete(dialog.FileName);

    return bitmap;
}

函数由事件处理程序调用:

private void _pictureBox_Click(object sender, EventArgs e)
{
    _takePictureLinkLabel.Visible = false;

    var image = Camera.TakePicture();
    if (image == null)
       return;

    image = Camera.CutBitmap(image, 2.5);
    _pictureBox.Image = image;

    _image = Camera.ImageToByteArray(image);
}

【问题讨论】:

    标签: .net .net-3.5 memory windows-mobile out-of-memory


    【解决方案1】:

    我怀疑你持有参考资料。作为一个次要原因,请注意在使用 ShowDialog 时对话框不会自行释放,因此您应该是 using 对话框(尽管我希望 GC 仍会收集未释放但未引用的对话框)。

    同样,您可能应该是using 图像,但同样:我不确定我是否希望这会成败;不过值得一试...

    public static Bitmap TakePicture()
    {
        string filename;
        using(var dialog = new CameraCaptureDialog
        {
            Resolution = new Size(1600, 1200),
            StillQuality = CameraCaptureStillQuality.Default
        }) {
    
            dialog.ShowDialog();
            filename = dialog.FileName;
        }    
        // If the filename is empty the user took no picture
        if (string.IsNullOrEmpty(filename))
           return null;
    
        // (!) The OutOfMemoryException is thrown here (!)
        var bitmap = new Bitmap(filename);
    
        File.Delete(filename);
    
        return bitmap;
    }
    
    private void _pictureBox_Click(object sender, EventArgs e)
    {
        _takePictureLinkLabel.Visible = false;
    
        using(var image = Camera.TakePicture()) {
            if (image == null)
               return;
    
            image = Camera.CutBitmap(image, 2.5);
            _pictureBox.Image = image;
    
            _image = Camera.ImageToByteArray(image);
        }
    }
    

    我也会对CutBitmap 等保持警惕,以确保尽快发布。

    【讨论】:

    • 我会稍微修改你的代码 - 在它设置图片框图像的地方,我会首先处理任何现有图像,例如 if(_pictureBox.Image != null) _pictureBox.Image.Dispose( )。
    【解决方案2】:

    您的移动设备通常没有任何内存交换到磁盘的选项,因此由于您选择将图像作为位图存储在内存中而不是磁盘上的文件,因此您很快就会消耗手机的内存。您的“new Bitmap()”行分配了大量内存,因此很可能会在那里引发异常。另一个竞争者是您的 Camera.ImageToByteArray,它将分配大量内存。这可能与您习惯使用计算机的情况相比并不大,但对于您的移动设备来说,这是巨大的

    尝试将图片保存在磁盘上,直到您使用它们,即将它们发送到网络服务。要显示它们,请使用您的内置控件,它们可能是最节省内存的,您通常可以将它们指向图像文件。

    干杯

    尼克

    【讨论】:

    • 没有“通常”。 CE 根本没有任何交换到磁盘的规定,因此没有设备可以这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    相关资源
    最近更新 更多