OracleBulkCopy 内存泄漏(OutOfMemory 异常)

mha*_*125 3 c# oracle memory-leaks bulkinsert sqlbulkcopy

下面是我用来将数据从临时表 dataTable 批量复制到 Oracle 数据库中的 destTable 的代码。dataTable 有大约 200 万条记录。

using (OracleBulkCopy bulkCopy = new OracleBulkCopy(VMSDATAConnectionString))
            {
                try
                {
                    foreach (OracleBulkCopyColumnMapping columnMapping in columnMappings)
                        bulkCopy.ColumnMappings.Add(columnMapping);

                    bulkCopy.DestinationTableName = destTableName;
                    //bulkCopy.BatchSize = dataTable.Rows.Count;
                    //bulkCopy.BulkCopyTimeout = 100;                   
                    int defaultSize = 5000;
                    int.TryParse(ConfigurationManager.AppSettings["OracleBulkCopyBatchSize"], out defaultSize);
                    bulkCopy.BatchSize = defaultSize;
                    int timeOut = 100;
                    int.TryParse(ConfigurationManager.AppSettings["OracleBulkCopyTimeout"], out timeOut);
                    bulkCopy.BulkCopyTimeout = timeOut;
                    Console.WriteLine("Bulk insert from {0} to {1} started at: {2}\r\nBatchSize : {3}, BulkCopyTimeout : {4} ", dataTable.TableName, destTableName, DateTime.Now.ToString("HH:mm:ss"), bulkCopy.BatchSize.ToString(), bulkCopy.BulkCopyTimeout.ToString());
                    bulkCopy.WriteToServer(dataTable);
                    Console.WriteLine("Bulk insert from {0} to {1} finished at: {2}", dataTable.TableName, destTableName, DateTime.Now.ToString("HH:mm:ss"));
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error happened during bulk copy from {0} to {1}\r\nBatchSize : {2}, BulkCopyTimeout : {3}\r\n Error message {4}", dataTable.TableName, destTableName, bulkCopy.BatchSize.ToString(), bulkCopy.BulkCopyTimeout.ToString(), ex.ToString());
                    bulkCopy.Close();
                    bulkCopy.Dispose();
                }
            }
Run Code Online (Sandbox Code Playgroud)

但它抛出以下异常: 在此处输入图片说明

运行这个数据加载过程的服务器肯定有足够的内存,看起来数据库服务器(linux)没有足够的内存。以下是数据库服务器内存屏幕截图: 在此处输入图片说明

任何人都可以帮助解决这个问题吗?谢谢。

mha*_*125 5

找到根本原因,exe 运行在 32 位并且它有 1.5G 内存限制。需要更改目标平台并将 Oracle.DataAccess.dll 替换为 64 位版本。

还有一个替代解决方案:批量加载数据,使其不会超过 1.5 G 内存限制。

更新:

“MEMORY LEAK USING ORACLEBULKCOPY”:oracle批量复制有一些导致内存泄漏的错误,当BatchSize小于数据表大小时发生。需要修改 BatchSize 或更新 ODAC 到更高版本。

参考:https : //community.oracle.com/message/4593452#4593452