public static long TotalMemoryUsageOf(params MemoryStatsVisitor_Visitable[] memoryUsers) { GatheringMemoryStatsVisitor memoryVisitor = new GatheringMemoryStatsVisitor(); foreach (MemoryStatsVisitor_Visitable memoryUser in memoryUsers) { memoryUser.AcceptMemoryStatsVisitor(memoryVisitor); } return(memoryVisitor.TotalUsage); }
/// <summary> /// Keeping all counts for all combinations of label/reltype can require a lot of memory if there are lots of those tokens. /// Each processor will allocate such a data structure and so in extreme cases the number of processors will have to /// be limited to not surpass the available memory limits. /// </summary> /// <param name="config"> <seealso cref="Configuration"/> holding things like max number of processors and max memory. </param> /// <param name="cache"> <seealso cref="NodeLabelsCache"/> which is the only other data structure occupying memory at this point. </param> /// <param name="highLabelId"> high label id for this store. </param> /// <param name="highRelationshipTypeId"> high relationship type id for this store. </param> /// <returns> number of processors suitable for this step. In most cases this will be 0, which is the typical value used /// when just allowing the importer to grab up to <seealso cref="Configuration.maxNumberOfProcessors()"/>. The returned value /// will at least be 1. </returns> private static int NumberOfProcessors(Configuration config, NodeLabelsCache cache, int highLabelId, int highRelationshipTypeId) { GatheringMemoryStatsVisitor memVisitor = new GatheringMemoryStatsVisitor(); cache.AcceptMemoryStatsVisitor(memVisitor); long availableMem = config.MaxMemoryUsage() - memVisitor.TotalUsage; long threadMem = RelationshipCountsProcessor.CalculateMemoryUsage(highLabelId, highRelationshipTypeId); long possibleThreads = availableMem / threadMem; return(possibleThreads >= config.MaxNumberOfProcessors() ? 0 : toIntExact(max(1, possibleThreads))); }