我刚刚开始使用ESENT ManagedInterface (http://managedesent.codeplex.com/)。我想知道它是否存在内存泄漏问题。
我所做的事情相当简单。我遵循示例代码,但我在每一行中放置了一个相当大的字符串数据(10KB+),总共生成了10000行。
当插入更多行时,内存使用量增加。如果我插入大约100,000行,该程序将占用1GB内存并死亡。
,这是代码.
public static void test()
{
string techcrunchString = @"The Latest from TechCrunch CMU Researchers Turn Any Surface Into A TouchscreenWeb Design Community Treehouse Raises $600K From Reid Hoffman, Kevin Rose, And Others Greylock Looks To Help Portfolio Companies Recruit Talent With New Hires UberMedia Quietly (Inadvertently?) Releases Chime.in, A Mobile Social Networking App T-Mobile Announces The Dual-Screen LG DoublePlay, Launching November 2nd? Watch An iPhone 4S and Samsung Galaxy S II Take Three Nasty Drops Onto Concrete Facebook, NRDC & Opower To Partner On Energy-Saving Social AppCTIAs New Alert Guidelines Could Mean The End Of Bill ShockGrockit Gets A $7 Million Venture Infusion And Launches Video Q&A Site Grockit AnswersGorgeous Photos, Tablet Browsing: 500px Debuts New iPad AppSamsung Galaxy Nexus, HTC Vigor To Launch November 10?Freelance.com: Facebook App, 3D, HTML5, And Cocoa Jobs On The RiseiPhone 4S First Weekend Sales Exceeds 4 Million, Doubles The Pace Of The iPhone 4Wahanda Secures $5.5 Million From Fidelity Growth Partners EuropeLook Out Uber: GroundLink Launches An Affordable, Mobile Private Car Service For New YorkersVideo Collaboration Software Maker ViVu Acquired By PolycomWith 400,000 Users Under Its Belt, SohoOS Plans Major Revamp5 Product Innovations From CEATEC 2011 In Japan (Video Gallery)Digital Media Companies Inuvo And Vertro To MergeRIM Apologizes With Free Apps & Technical Support For Three Days Of DowntimeCMU Researchers Turn Any Surface Into A TouchscreenPosted: 17 Oct 2011 09:14 AM PDT";
JET_INSTANCE instance;
JET_SESID sesid;
JET_DBID dbid;
JET_TABLEID tableid;
JET_COLUMNDEF columndef = new JET_COLUMNDEF();
// Initialize ESENT. Setting JET_param.CircularLog to 1 means ESENT will automatically
// delete unneeded logfiles. JetInit will inspect the logfiles to see if the last
// shutdown was clean. If it wasn't (e.g. the application crashed) recovery will be
// run automatically bringing the database to a consistent state.
Api.JetCreateInstance(out instance, "instance");
Api.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.CircularLog, 1, null);
Api.JetInit(ref instance);
Api.JetBeginSession(instance, out sesid, null, null);
// Create the database. To open an existing database use the JetAttachDatabase and
// JetOpenDatabase APIs.
Api.JetCreateDatabase(sesid, "edbtest.db", null, out dbid, CreateDatabaseGrbit.OverwriteExisting);
// Create the table. Meta-data operations are transacted and can be performed concurrently.
// For example, one session can add a column to a table while another session is reading
// or updating records in the same table.
// This table has no indexes defined, so it will use the default sequential index. Indexes
// can be defined with the JetCreateIndex API.
Api.JetBeginTransaction(sesid);
Api.JetCreateTable(sesid, dbid, "table", 0, 100, out tableid);
JET_COLUMNID id;
columndef.coltyp = JET_coltyp.Binary;
columndef.cp = JET_CP.ASCII;
Api.JetAddColumn(sesid, tableid, "id", columndef, null, 0, out id);
JET_COLUMNID blob;
columndef.coltyp = JET_coltyp.LongBinary;
//columndef.cp = JET_CP.ASCII;
Api.JetAddColumn(sesid, tableid, "blob", columndef, null, 0, out blob);
string indexDef = "+id\0\0";
Api.JetCreateIndex(sesid, tableid, "primary", CreateIndexGrbit.IndexPrimary, indexDef, indexDef.Length, 100);
//Api.JetSetCurrentIndex(sesid, tableid, null);
Api.JetCommitTransaction(sesid, CommitTransactionGrbit.LazyFlush);
long Process_MemoryStart = 0;
Process MyProcess = System.Diagnostics.Process.GetCurrentProcess();
Process_MemoryStart = MyProcess.PrivateMemorySize64;
Console.WriteLine("Before loop : " + Process_MemoryStart / 1024 + "KB");
int i = 0;
for (int t = 0; t < 20; t++)
{
Api.JetBeginTransaction(sesid);
for (int j = 0; j < 500; j++)
{
i = t * 500 + j;
string dataString = techcrunchString + i.ToString();
byte[] data = Encoding.UTF8.GetBytes(dataString);
string keyString = i.ToString();
byte[] key = Encoding.UTF8.GetBytes(keyString);
//store
Api.MakeKey(sesid, tableid, key, MakeKeyGrbit.NewKey);
bool exists = Api.TrySeek(sesid, tableid, SeekGrbit.SeekEQ);
if (exists)
{
Api.JetPrepareUpdate(sesid, tableid, JET_prep.ReplaceNoLock);
//Console.WriteLine("store: " + "update");
}
else
{
Api.JetPrepareUpdate(sesid, tableid, JET_prep.Insert);
Api.SetColumn(sesid, tableid, id, key);
//Console.WriteLine("store: " + "insert");
}
Api.SetColumn(sesid, tableid, blob, data);
Api.JetUpdate(sesid, tableid);
if (i % 500 == 0)
{
long Process_MemoryStart1 = 0;
Process MyProcess1 = System.Diagnostics.Process.GetCurrentProcess();
Process_MemoryStart1 = MyProcess1.PrivateMemorySize64;
Console.WriteLine("Finished " + i.ToString() + " : " + Process_MemoryStart1 / 1024 + "KB");
}
}
Api.JetCommitTransaction(sesid, CommitTransactionGrbit.None);
}
Process_MemoryStart = 0;
MyProcess = System.Diagnostics.Process.GetCurrentProcess();
Process_MemoryStart = MyProcess.PrivateMemorySize64;
Console.WriteLine("Loop finished: " + Process_MemoryStart / 1024 + "KB");
// Terminate ESENT. This performs a clean shutdown.
Api.JetCloseTable(sesid, tableid);
Process_MemoryStart = 0;
MyProcess = System.Diagnostics.Process.GetCurrentProcess();
Process_MemoryStart = MyProcess.PrivateMemorySize64;
Console.WriteLine("After close table: " + Process_MemoryStart / 1024 + "KB");
Api.JetEndSession(sesid, EndSessionGrbit.None);
Process_MemoryStart = 0;
MyProcess = System.Diagnostics.Process.GetCurrentProcess();
Process_MemoryStart = MyProcess.PrivateMemorySize64;
Console.WriteLine("After end session: " + Process_MemoryStart / 1024 + "KB");
Api.JetTerm(instance);
Process_MemoryStart = 0;
MyProcess = System.Diagnostics.Process.GetCurrentProcess();
Process_MemoryStart = MyProcess.PrivateMemorySize64;
Console.WriteLine("After term instance: " + Process_MemoryStart / 1024 + "KB");
}在上面的代码中,它高达大约100 MB。只有当我执行Api.JetTerm(实例)时,内存才被释放。
在我真正的问题中,我不得不多次不断地插入大量数据,所以它不会以这种方式工作,因为内存最终会被消耗掉。
有人能帮我吗?
**为什么即使我完成了交易,也保留着内存?
我怀疑是esent内部的撤销东西保存了内存,如果是,如何关闭它?我不需要撤销**
谢谢
P.S:我在32位和64位Windows中都尝试过这个test()方法,它们都有相同的内存问题。
发布于 2011-10-17 17:48:07
这会有什么帮助吗:http://www.nikosbaxevanis.com/bonus-bits/2010/10/adventures-using-rhino-servicebus.html?
Microsoft.Isam.Esent.Interop.JET_param,CacheSizeMax此参数配置数据库页缓存的最大大小。大小在数据库页中。如果将此参数保留为其默认值,则在调用JetInit时,缓存的最大大小将设置为物理内存的大小。将Microsoft.Isam.Esent.Interop.SystemParameters.CacheSizeMax设置为1024或512似乎解决了内存使用量增加的问题。
发布于 2012-06-21 00:43:16
抱歉,我来晚了.
我要注意的是,这样做并不是修复内存泄漏,而是降低了引擎的性能。缓存的大小是缓存内存中的数据库页,这样您就可以像一个好的数据库那样访问磁盘less...just。)如果减少这种情况,就会对perf造成伤害,需要更多的磁盘IO。
数据库引擎是足够明智的,当它看到其他人使用内存时,所以从理论上说,您不应该拥有这样的缓存大小,如果它看到其他人想要缓存,它就会释放内存。
所以,net,除非您真的知道您需要这样做,否则我不会推荐它。
https://stackoverflow.com/questions/7797450
复制相似问题