Itgenclr007: System.OutOfMemoryException bij ChunkedDiskCacheStream

Probleem zoals beschreven bij Error itgendhb212: External error in Invantive Data Hub. (out of memory) treedt weer op (bij andere klant).

Dit keer werkt het toevoegen niet van de regel voor uitschakelen disk cache.

Hierbij een iets uitgebreidere versie van de foutmelding. Enig idee waar dit door komt?

One or more errors occurred.
Exception of type ‘System.OutOfMemoryException’ was thrown.
2021-04-29 09:07:23.297 Error itgenclr007: System.OutOfMemoryException
System.OutOfMemoryException
at System.IO.MemoryStream.ToArray()
at Invantive.Data.Providers.ExactOnline.ChunkedDiskCacheStream.T()
at Invantive.Data.Providers.ExactOnline.ChunkedDiskCacheStream.Close()
at Invantive.Data.Providers.ExactOnline.ExactOnlineRestProvider.IQU.MoveNext()
at Invantive.Data.GenericProvider.QSC.MoveNext()
at (Object )
at IBC.DF.R(Object )
at Invantive.Basics.ExtensionMethods.ZB1.MoveNext() at Invantive.Data.Providers.DataCache.DataCacheProvider.MaintainTablePartitionVersionFactsOnePartition(GlobalState owner, ExecutionOptions executionOptions, ObjectDefinition objectDefinition, DatabaseColumnDefinitionCollection resultFields, Lazy1 fetchFullDataSet, Boolean mayReplaceWithCachedData, String sourceDataContainerId, String partitionCode, IDataProvider dataSourceProvider, QueryObject originalQueryObject, Nullable1 maxAgeDataMs, Decimal version, DcTablePartitionVersion previousReadyTablePartitionVersion, String refreshOrigin, PartitionData& replacementPartitionData) at Invantive.Data.Providers.DataCache.DataCacheProvider.RefreshTablePartition(GlobalState owner, ExecutionOptions executionOptions, IProviderManager manager, Decimal tablePartitionId, String sourceDataContainerId, String dataContainerAlias, String fullQualifiedName, String partitionCode, Nullable1 versionLast, DcUpdateStrategy originalUpdateStrategy, Decimal dcrId, Decimal ptnId, Decimal tbeId, Int64& countWithDefaultLoading, Int64& countWithSmartSampling, Int64& countWithTrickleLoading, Nullable1& maxIncomingMessageId, Boolean& usedCompleteCopyInsteadOfTrickleLoading) at Invantive.Data.Providers.DataCache.DataCacheProvider.RefreshObsoleteTablePartitionsPerPartition(GlobalState owner, ExecutionOptions executionOptions, IProviderManager manager, String dataContainerId, String dataContainerAlias, String partitionName, VUH[] obsoleteTablePartitions, Int64 parallelLoopIndex, DcUpdateStrategy forcedUpdateStrategy, ConcurrentBag1 allExceptions, Int64& countWithDefaultLoading, Int64& countWithSmartSampling, Int64& countWithTrickleLoading, Int64& countUpdatedTablePartitions, Int64& countNoActionTablePartitions, Int64& countFailedTablePartitions, Int64& countWithFallbackToCompleteCopy)
System.OutOfMemoryException
at Newtonsoft.Json.JsonTextReader.PrepareBufferForReadData(Boolean append, Int32 charsRequired)
at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append, Int32 charsRequired)
at Newtonsoft.Json.JsonTextReader.ReadStringIntoBuffer(Char quote)
at Newtonsoft.Json.JsonTextReader.ParseString(Char quote, ReadType readType)
at Newtonsoft.Json.JsonTextReader.ReadAsBytes()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
at Invantive.Basics.HttpResponseCacheObject.FromJson(GlobalState owner, ExecutionOptions executionOptions, String json, String& reasonNull)
at Invantive.Data.GenericProvider.TryGetHttpFromDiskCache(GlobalState owner, ExecutionOptions executionOptions, CacheSettings cacheSettings, String cacheId, Nullable`1 maxAgeSec, Boolean expectEncryption, String expectedUrl, String dataContainerId, HttpResponseCacheObject& cacheObject)
at Invantive.Data.Providers.ExactOnline.ExactOnlineRestProvider.DQU.V(ReadChunkData )
at Invantive.Data.Providers.ExactOnline.ChunkedDiskCacheStream.P()
at Invantive.Data.Providers.ExactOnline.ChunkedDiskCacheStream.V(Byte[] , Int32 , Int32 )
at Invantive.Data.Providers.ExactOnline.ChunkedDiskCacheStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.StreamReader.ReadBuffer(Char[] userBuffer, Int32 userOffset, Int32 desiredChars, Boolean& readToUserBuffer)
at System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count)
at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append, Int32 charsRequired)
at Newtonsoft.Json.JsonTextReader.ParseValue()

Ik heb inmiddels een soort oplossing, maar weet niet zo zeer hoe deze verband houdt met de melding.

mogelijke oplossing:

Soms als ik de Windows Task Manager open draait de Invantive Data Hub twee keer (los van elkaar).

Als ik ze dan allebei sluit en opnieuw draait gaat alles goed.

Vraag blijft: hoe komt dit, en waar komt OutOfMemory dan vandaan.

Dan zou het echt een OutOfMemoryException zijn, namelijk dat het werkgeheugen “op” is. De twee processen zien elkaar niet anders dan via Data Replicator Repository, ze hebben ook elk een AppDomain.

Advies is om te controleren dat er een 64-bit versie van Windows gebruikt wordt en dat er in Taakbeheer ook zichtbaar is dat er ruim voldoende (virtueel) geheugen beschikbaar is.

(De vraag stond oorspronkelijke bericht onder het bovenaan genoemde topic, afgesplitst naar apart topic omdat het een nieuwe vraag is)

De oorspronkelijke foutmelding was bij vorige antwoord niet meegenomen; bij oppervlakkige controle leek het een ouder bericht.

Kijkend naar de volledige melding, lijkt er sprake te zijn van de nieuwe *Incremental tabellen op basis van de Exact Online sync API’s. Die leggen de laatst bekende toestand vast op schijf. Gezien de mogelijk grote omvang (10 miljoenen boekingen is circa 20 GB ruwe data) gebeurt deze vastlegging niet in 1 grote file, maar verspreid over meerdere bestanden, zogenaamde chunks, met daarnaast een stukje metadata die beschrijft welke bestanden samen de inhoud van één administratie en één tabel vormen.

De huidige nagestreefde grootte van een chunk is 100 MB na decompressie.

Een file met een chunk bevat JSON; die wordt omgezet naar een structuur in het geheugen. Gedurende deze omzetting zal er een kortstondige piek in het geheugengebruik zijn. Een chunkgrootte van 100 MB moet er voor zorgen dat de theoretische en praktische limiet van 2 GB voor een tekst geen hindernis vormt (alleen 64-bit processen). Toch treedt bij het omzetten (“deserialiseren”) een OutOfMemory op in PrepareBufferForReadData.

Advies is om te controleren dat de machine voldoende beschikbaar werkgeheugen heeft en dat het programma in 64-bit draait. Een link naar de systeemberichten URL zou ook helpen.