我在这里和网上的其他地方查看了所有答案,但我无法找到我正在寻找的内容。我们来看看:
我正在使用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问题面前。 我认为它不会释放为阵列分配的内存。
对不起我的英语,问候并感谢你。