移动设备上的OutOfMemoryException

时间:2009-02-27 08:21:01

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

我正在开发一个使用移动设备拍摄照片并使用网络服务发送的应用程序。但是在我拍了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);
}

2 个答案:

答案 0 :(得分:5)

我怀疑你持有引用。作为次要原因,请注意在使用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等有点谨慎,以确保尽快发布内容。

答案 1 :(得分:2)

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

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

干杯

的Nik