数组和NHibernate的OutOfMemoryException,¿释放内存严重?

时间:2017-02-07 15:16:21

标签: c# arrays nhibernate out-of-memory

我在这里和网上的其他地方查看了所有答案,但我无法找到我正在寻找的内容。我们来看看:

我正在使用NHibernate(文件版本3.0.0.4000)。另外,我有一个在NHibernate中映射的主 - 细节实体模型。由于我需要插入具有数百万个这样的批处理,因此主实体具有断开的细节集合。因此,我将明确处理持久性。

问题是我试图保留很多细节(有一个byte属性[]),显然,没有释放数组的已分配内存。

持久性算法:

private Master BasicSave(Master entity)
{
    base.Save(entity);

    this.Session.CacheMode = NHibernate.CacheMode.Ignore;
    var ddContext = DetachedDetailContext.Current;
    if (ddContext != null)
    {
        var details = ddContext.DetachedDetailSession.GetItemsToInsert(entity, true);
        var detailsCant = details.Count;
        var cant = 0;

        for (var i = 1; i <= detailsCant; i++)
        {
            var item = details[0];
            details.RemoveAt(0);

            this.Session.Save(item);

            if (i % DetachedDetailSettings.Instance.ChangesetMaxSize == 0)
            {
                cant = cant + 1;
                Console.WriteLine("Flush Nro: " + cant.ToString());
                this.Session.Flush();
                this.Session.Clear();
            }
        }
    }

    return entity;
}

我想要保留的详细信息实体包含一个定义为:

的列
public virtual byte[] Archivo { get; set; } //(file)

但是,似乎Flush()和Clear()指令不会释放数组内存。因为我收到带有以下调用堆栈的OutOfMemoryException:

at NHibernate.Type.AbstractBinaryType.DeepCopyNotNull(Object value) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Type\AbstractBinaryType.cs:line 149
at NHibernate.Type.MutableType.DeepCopy(Object value, EntityMode entityMode, ISessionFactoryImplementor factory) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Type\MutableType.cs:line 48
at NHibernate.Type.TypeHelper.DeepCopy(Object[] values, IType[] types, Boolean[] copy, Object[] target, ISessionImplementor session) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Type\TypeHelper.cs:line 33
at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Event\Default\AbstractSaveEventListener.cs:line 248
at NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Event\Default\AbstractSaveEventListener.cs:line 187
at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Event\Default\AbstractSaveEventListener.cs:line 119
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Event\Default\DefaultSaveOrUpdateEventListener.cs:line 162
at NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Event\Default\DefaultSaveEventListener.cs:line 29
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Event\Default\DefaultSaveOrUpdateEventListener.cs:line 148
at NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Event\Default\DefaultSaveEventListener.cs:line 21
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Event\Default\DefaultSaveOrUpdateEventListener.cs:line 53
at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 2590
at NHibernate.Impl.SessionImpl.Save(Object obj) in D:\Samples\nhibernate\trunk\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 473
at Produccion.Persistence.DAOsNHImpl.MasterDAO.BasicSave(Master entity) in c:\SCS\wf_net\devnet_prod\branch\Inbroker\RefactorDetachedDetail\Modulos\Produccion\BackEnd\Persistence\DAOsNHImpl\MasterDAO.cs:line 53
at Produccion.Persistence.DAOsNHImpl.MasterDAO.<Save>b__0(Master x) in c:\SCS\wf_net\devnet_prod\branch\Inbroker\RefactorDetachedDetail\Modulos\Produccion\BackEnd\Persistence\DAOsNHImpl\MasterDAO.cs:line 27
at Core.DAOs.NHImpl.NHibernateDAOHelper.ExecuteInTransaction[TBe](ISession session, OperationResult`1 operation, TBe be) in c:\SCS\Branches\v5.19.00\Core\Core.DAOs.NHImpl\NHibernateDAOHelper.cs:line 213

以下是NHibernate.Type.AbstractBinaryType.DeepCopyNotNull(Object value)的定义:

public override object DeepCopyNotNull(object value)
{
    byte[] bytes = ToInternalFormat(value);
    byte[] result = new byte[bytes.Length];
    Array.Copy(bytes, 0, result, 0, bytes.Length);
    return ToExternalFormat(result);
}

测试代码片段(我正在读取1MB文件):

using (new UseCaseTest())
{
    using (var context = new TransactionManagerContext(new TransactionManager()))
    {
        Console.WriteLine("INICIO INSERT");
        context.BeginTransaction();
        var stopwatch = Stopwatch.StartNew();
        using (var uow = new DetachedDetailContext(new NHDetachedDetailSession(NHibernateSessionManager.Instance.GetSessionFrom("defaultSessionFactory"))))
        {
            var be = new Master();
            be.Descripcion = "nuevo";
            be.UltimoEstado = true;
            be.Otro = "otro_test";
            var archivo = System.IO.File.ReadAllBytes("C:\\IMGTST.JPG");

            for (int i = 0; i < K_CantDetalles; i++)
            {
                var beDetalle = new Detalle();
                beDetalle.Descripcion = string.Format("Detalle ({0})", i.ToString());
                beDetalle.Numero = i;
                beDetalle.Archivo = archivo;
                beDetalle.Importe = i + 2.5M;
                beDetalle.UltimoEstado = true;
                be.AgregarDetalle(beDetalle);
            }

            //Save
            be = this.MasterDAO.Save(be);
            beAnteriorId = be.Id;

        }

        context.FinalizeTransaction();
    }
}

我无法确定我的解决方案是否存在问题(可能维护不必要的对象引用),或者我在NHibernate问题面前。 我认为它不会释放为阵列分配的内存。

对不起我的英语,问候并感谢你。

0 个答案:

没有答案