OutOfMemoryException on image retrieval
CapableObjects Forums
Home       Members    Calendar    Who's On
Welcome Guest ( Login | Register )
        



OutOfMemoryException on image retrieval Expand / Collapse
Author
Message
Posted 2010-05-19 17:31:30
Forum Newbie

Forum NewbieForum NewbieForum NewbieForum NewbieForum NewbieForum NewbieForum NewbieForum Newbie

Group: Forum Members
Last Login: 2010-05-20 17:30:04
Posts: 7, Visits: 24
I am getting an OutOfMemoryException when retrieving images from my SQLite database. My Observation object has many ObservationImage objects which have an ImageData property containing a jpg image file (about 5MB per file). I am looping through these images and streaming them to a directory on the local filesystem. After about 50 Observations (100 images) I get this exception.

Is there a way of clearing the memory used by the image after I have used its data (after exporting to a directory)?

My Code is as follows:



foreach (Observation Obs in Surv.Observations) {
DirPath = outputPath + String.Format("\\Obs {0}", Obs.ID);
ExportObservationImagesToPath(Obs, DirPath);
prog.Position = ObsNum++;
prog.Update();
}

private void ExportObservationImagesToPath(Observation obs, string dirPath) {
if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
string FilePath;
byte[] BinData;
int ImageNum = 1;
foreach (ObservationImage Image in obs.ObservationImages) {
FilePath = Path.Combine(dirPath, string.Format("Obs {0} Image {1}.jpg", obs.ID, ImageNum++));
BinData = Image.ImageData;
BinaryFile.SaveBufferToFile(ref BinData, FilePath);
}
}




The exception detail is as follows;



System.InvalidOperationException was unhandled by user code
Message="Error retrieving data for ObservationImage.ImageData: An error occurred when reading query field value for ObservationImage.ImageData\rError: OutOfMemoryException\rMessage: Exception of type 'System.OutOfMemoryException' was thrown."
Source="Eco.Persistence"
StackTrace:
at Eco.Persistence.Impl.ClassPersistenceMapper.ValuesFromFieldsByMemberList(ObjectContents ObjContents, InexactIdList RequiresExactification, IDataSet DataSet, TBoldMemberPersistenceMapperList memberList) in e:\dev\fbuild\source\Eco\Eco.Persistence\FromCore\ClassPersistenceMapper.cs:line 840
at Eco.Persistence.Impl.ClassPersistenceMapper.PMMultiPurposeRetrieveExactIdList(IDatabaseCollection Databases, ObjectIdCollection ObjectsToFetch, Datablock Precondition, Int32[] MemberIdList, FetchMode FetchMode, IdTranslationList TranslationList, Datablock FailureList, Int32 Timestamp, FetchStrategy fetchStrategy) in e:\dev\fbuild\source\Eco\Eco.Persistence\FromCore\ClassPersistenceMapper.cs:line 1542

... other detail deleted ....



Any help would be gratefully received,

VS2008 SP 1 ECO5 (latest release version)


Mike
Post #5229
Posted 2010-05-20 10:24:38
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

Group: Forum Members
Last Login: 2011-07-14 17:05:00
Posts: 290, Visits: 2 617
Hi Mike

When you load these objects ECO keeps them in its cache until you close the EcoSpace, which means each image data remains in memory. There are two ways you can tackle this

Solution 1:
Make sure the image data is marked as DelayedFetch=True
Pass the ExternalID rather than the Observation object
Create an EcoSpace, get the object by its ExternalID, Save the image, dispose of the EcoSpace

1 initial select to get the list of observation + 1 select for each observation data + 1 select for each delayed fetched image data


Solution 2:
Make sure the image data is marked as DelayedFetch=True
After passing the Observation object to your routine which saves the image unload it

1 initial select to get the list of observation + 1 select for each 50 observation data objects + 1 select for each delayed fetched image data

foreach(var observation in Meh.Observations)
{
SaveTheImage(observation, .........);
observation.AsIObject().ServiceProvider.GetEcoService().Unload(new List { observation });
}

I think the latter will work, give it a try, but either way you really want a DelayedFetch=True


====
Pete
Post #5230
Posted 2010-05-20 17:31:05
Forum Newbie

Forum NewbieForum NewbieForum NewbieForum NewbieForum NewbieForum NewbieForum NewbieForum Newbie

Group: Forum Members
Last Login: 2010-05-20 17:30:04
Posts: 7, Visits: 24
Thanks Pete,

I adopted your second approach which seems to have solved the issue. Many thanks as always.

Regards


Mike
Post #5231
« Prev Topic | Next Topic »


Reading This Topic Expand / Collapse
Active Users: 0 (0 guests, 0 members, 0 anonymous members)
No members currently viewing this topic.
Forum Moderators: HansKarlsen, Jonas Hogstrom, PeterMorris

Permissions Expand / Collapse

All times are GMT +1:00, Time now is 9:57

Powered By InstantForum.NET v4.1.4 © 2012
Execution: 0,063. 9 queries. Compression Disabled.