C# 频繁申请数组偶尔报错OutOfMemoryException

如图, 频繁申请新的数组,导致偶尔报错OutOfMemoryException(重点:偶尔),很奇怪的问题,明明内存够,却报错OutOfMemoryException。

分析:数组地址是连续的,我这是图片数据,大小可能有的大,导致频繁申请新的连续地址不够,以前使用过的数组GC又没有来得及回收(大概140ms申请一次连续地址),所以报此错。

解决方案:1.直接加内存(开玩笑)

2.程序启动申请一个固定大小的内存地址,每次去覆盖此数组的值,而不去创建新的地址。

自己封装了一个类使用如下:

public class LargeArray
    {
        private readonly int _capacity;
        private readonly int _arraySize;
        private readonly byte[][] _array;
        private volatile int _currentIndex = 0;
        public LargeArray(int capacity, int arraySize)
        {
            if (capacity <= 0 || arraySize <= 0)
                throw new Exception("大小必须大于0");

            this._capacity = capacity;
            this._arraySize = arraySize;
            this._array = new byte[capacity][];
            for (int i = 0; i < capacity; i++)
            {
                this._array[i] = new byte[arraySize];
            }
        }
        public int ArraySize
        {
            get
            {
                return this._arraySize;
            }
        }
        public int Capacity
        {
            get
            {
                return this._capacity;
            }
        }
        public int CurrentIndex
        {
            get
            {
                return this._currentIndex;
            }
            private set
            {
                if (value == this.Capacity)
                    value = 0;
                this._currentIndex = value;
            }
        }
        public IntPtr Pointer
        {
            set
            {
                Marshal.Copy(value, ArrayData, 0, this._arraySize);
            }
        }
        public byte[] ArrayData
        {
            get
            {
                return this._array[CurrentIndex];
            }
            set
            {
                this._array[CurrentIndex++] = value;
            }
        }
    }

这里的capacity是创建几个大小相同的数组,arraySize是每个数组的大小。

使用:

_largeArray是全局变量,最终获取数组_largeArray.ArrayData就可(注意:在使用的时候需要及时使用,因为会被后面的覆盖,如果来不及使用,可以把capacity设置大一点,最好合理的大小,太大会浪费资源) 。本例子中_largeArray.Pointer = e.Pointer将值赋值到数组,然后Data = _largeArray.ArrayData立马加入到队列等待使用,此时绘图线程可能来不及使用,但是我开启了3个,所以中间有一定的缓冲,设置capacity越大,缓冲时间越长,开销的内存资源就越多,如果来不及使用就会被覆盖,图像要么出现跳要么就出现乱。

ps:我这里创建图像线程只负责生产数组数据,不绘图,绘图在另外的线程,可能会慢点,所以我这里设置3个数组作为绘图线程的缓冲。

对比之前的图像,现在的内存反而降低了不少。。。 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值