用sqlbulkcopy插入数据库内存不释放

six-years 2017-11-09 05:34:18
系统用sqlbulkcopy插入数据库所占内存越来越大,大家有什么解决方法么
...全文
588 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
吉普赛的歌 2017-11-10
  • 打赏
  • 举报
回复
        static void test()
        {
            DataTable dtTemplate = new DataTable();
            dtTemplate.Columns.Add("id", typeof(int));
            dtTemplate.Columns.Add("ColumnsA", typeof(string));
            dtTemplate.Columns.Add("ColumnsB", typeof(string));
            dtTemplate.Columns.Add("ColumnsC", typeof(string));
            dtTemplate.Columns.Add("ColumnsD", typeof(string));
            dtTemplate.Columns.Add("ColumnsE", typeof(string));

            while (true)
            {
                //1.这里另外用一个 DataTable , 只克隆结构
                DataTable dt = dtTemplate.Clone();
                for (int j = 0; j < 5000; j++)
                {
                    dt.Rows.Add(new object[] { null, "ColumnsA", "ColumnsB", "ColumnsC", "ColumnsD", "ColumnsE" });
                }
                BulkToDB(dt, "TEST");
                //2.用完就释放
                dt.Dispose();
                Thread.Sleep(100);
            }
        }

        static bool BulkToDB(DataTable sourceDt, string targetTable)
        {
            using (SqlConnection conn = new SqlConnection(_strConn))
            {
                conn.Open();
                using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn))
                {
                    bulkCopy.DestinationTableName = targetTable;
                    bulkCopy.BatchSize = 1000;  //3.这里改成 1000
                    try
                    {
                        bulkCopy.WriteToServer(sourceDt);  //写入数据库注释后内存正常释放
                        return true;
                    }
                    catch
                    {
                        return false;
                    }
                }
            }
        }
这样试试。 另外,如果你的数据源也是数据库的话,可以不用 DataTable , SqlBulkCopy 的数据源用 IDataReader , 根本占不了什么内存。
six-years 2017-11-10
  • 打赏
  • 举报
回复
引用 10 楼 Runnerchin 的回复:
因为你dt里一直有内容,往数据库里写完以后的确是清掉了数据,但是你隔了0.1秒数据又填满了。运行到sleep打个断点再观察一下。
打了断点内存也不会减小,代码中写入数据库那一句话注释后占用内存就不会持续变大了,所以还是标题上的问题sqlbulkcopy插入数据库内存不释放。
X-i-n 2017-11-10
  • 打赏
  • 举报
回复
因为你dt里一直有内容,往数据库里写完以后的确是清掉了数据,但是你隔了0.1秒数据又填满了。运行到sleep打个断点再观察一下。
six-years 2017-11-10
  • 打赏
  • 举报
回复
引用 8 楼 yenange 的回复:
为什么要 while(true) ? 另外你的数据来源是什么?不可能自己搞些数据出来吧?
这是是个测试函数哦,如果给你看实际代码就更乱了,while(true)肯定是业务需要的,测试代码模拟的就是实时采集数据插入数据库。
吉普赛的歌 2017-11-10
  • 打赏
  • 举报
回复
为什么要 while(true) ? 另外你的数据来源是什么?不可能自己搞些数据出来吧?
six-years 2017-11-10
  • 打赏
  • 举报
回复
引用 6 楼 yenange 的回复:
SqlBulkCopy 并不会引起内存爆涨。 出问题的地方在于 DataTable , 内存表才是大户, 才是源头。 你贴一下你的代码, 让我们帮你看看是否有优化的空间。
引用 5 楼 duanzi_peng 的回复:
[quote=引用 3 楼 six-years的回复:][quote=引用 2 楼 duanzi_peng 的回复:] 加内存。
加多少也有满的时候[/quote] 你不贴出执行代码,就加内存喽。[/quote]

static void test()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("id", typeof(int));
            dt.Columns.Add("ColumnsA", typeof(string));
            dt.Columns.Add("ColumnsB", typeof(string));
            dt.Columns.Add("ColumnsC", typeof(string));
            dt.Columns.Add("ColumnsD", typeof(string));
            dt.Columns.Add("ColumnsE", typeof(string));
            while (true)
            {
                for (int j = 0; j < 5000; j++)
                {
                    dt.Rows.Add(new object[] { null, "ColumnsA", "ColumnsB", "ColumnsC", "ColumnsD", "ColumnsE" });
                }
                BulkToDB(dt, "TEST");
                dt.Rows.Clear();
                Thread.Sleep(100);
            }
        }



static bool BulkToDB(DataTable sourceDt, string targetTable)
        {
            using (SqlConnection conn = new SqlConnection(_strConn))
            {
                conn.Open();
                using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn))
                {
                    bulkCopy.DestinationTableName = targetTable;
                    bulkCopy.BatchSize = sourceDt.Rows.Count;
                    try
                    {
                        bulkCopy.WriteToServer(sourceDt);  //写入数据库注释后内存正常释放
                        return true;
                    }
                    catch
                    {
                        return false;
                    }
                }
            }
        }

exception92 2017-11-10
  • 打赏
  • 举报
回复
引用 7 楼 Q1092926267 的回复:
[quote=引用 6 楼 yenange 的回复:] SqlBulkCopy 并不会引起内存爆涨。 出问题的地方在于 DataTable , 内存表才是大户, 才是源头。 你贴一下你的代码, 让我们帮你看看是否有优化的空间。
引用 5 楼 duanzi_peng 的回复:
[quote=引用 3 楼 six-years的回复:][quote=引用 2 楼 duanzi_peng 的回复:] 加内存。
加多少也有满的时候[/quote] 你不贴出执行代码,就加内存喽。[/quote] [/quote] 任何方法名称不要用static标识。 目测是你的BulkToDB 参数中的 sourceDt 没有释放,应该这样: bulkCopy.WriteToServer(sourceDt); //写入数据库注释后内存正常释放 sourceDt.Dispose(); return true;
吉普赛的歌 2017-11-09
  • 打赏
  • 举报
回复
SqlBulkCopy 并不会引起内存爆涨。 出问题的地方在于 DataTable , 内存表才是大户, 才是源头。 你贴一下你的代码, 让我们帮你看看是否有优化的空间。
exception92 2017-11-09
  • 打赏
  • 举报
回复
引用 3 楼 six-years的回复:
[quote=引用 2 楼 duanzi_peng 的回复:] 加内存。
加多少也有满的时候[/quote] 你不贴出执行代码,就加内存喽。
six-years 2017-11-09
  • 打赏
  • 举报
回复
引用 1 楼 starfd 的回复:
每次执行完立刻GC.Collect强制回收试试 注意你的DataTable什么的不能设为全局变量,不然回收不了
datatable是局部变量。
six-years 2017-11-09
  • 打赏
  • 举报
回复
引用 2 楼 duanzi_peng 的回复:
加内存。
加多少也有满的时候
exception92 2017-11-09
  • 打赏
  • 举报
回复
加内存。
  • 打赏
  • 举报
回复
每次执行完立刻GC.Collect强制回收试试 注意你的DataTable什么的不能设为全局变量,不然回收不了

110,552

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧