Collection has reached its maximum capacity
Author: superticker
Creation Date: 4/1/2015 10:28 AM
profile picture

superticker

#1
The following error message about (symbol) collections having memory problems appears when simulating with my largest dataset (183 symbols).
QUOTE:
Error in Visualizer: TabPage: {By Symbol}, removing. Collection has reached its maximum capacity.

There are no error messages for the smaller datasets, and the smallest datasets simulate fast. In addition, when simulating with large datasets, Wealth-Lab completes the "trading step" of the simulation very quickly, but then gets very slow (program won't respond to Windows events) during the "Compiling Performance Results" step. IMPORTANT: When the Symbols Tab is not computed (either interactively or by Strategy Monitor), the simulation executes in less than a second; it's super fast! And there's no error message.

My guess is that Wealth-Lab is caught up in garbage collection (heap storage) during the statistics compilation step. My questions are:

1) What can be done to reduce the burden on heap storage (for C# collections) to speed up the statistics compilation step? After simulation, the Symbols Tab shows many columns of results (Too many to count. Gesh! And most latter columns contain mostly zeros.) I don't need all those results. Only the first few columns are important to me. (Note: I have four panes of five time series on the strategy chart. About ten cached indicators are used in the intermediate calculations.)

2) Would increasing the heap storage be a solution? (Perhaps not the best solution.) Can this be done on the Windows Run command when "64-bit Wealth-Lab" loads? My workstation is running 64-bit Windows 7 with 16GB RAM.
profile picture

Eugene

#2
Your strategy has created way too many DataSeries, most likely in a dynamic manner in the loop. Each DataSeries is then added to the ListView. This is the reason behind "Collection has reached its maximum capacity" and the slowdown you're experiencing (ListViews are resource intensive).

To avoid pushing the limits, uncheck that PV when working with that Strategy (as you already found out) or optimize the code -- for example, by creating less interim DataSeries and/or calling Bars.Cache.Clear at the end to force clear the DataSeries cache and free up some RAM.
profile picture

superticker

#3
QUOTE:
Your strategy has created way too many DataSeries,... Each DataSeries is then added to the ListView.

Is every DataSeries created (even with the "new" operator) going to be added to a ListView "C# collection"? If so, is there a way to prevent this?

I realize if you create a DataSeries with the Class.Series() member function it will be cached, and if you create it with the "new" operator it will not be cached. (Nice feature.) But are all created DataSeries (cached or not) going to be added to the ListView automatically? If so, this is a bad feature.

The code below creates three ListView columns by default:
CODE:
Please log in to see this code.

It's okay to create a ListView column (in the By Symbol tab) for compositeExit because that DataSeries is charted (and of interest to me), but creating the other two ListViews is silly because I will never look at those columns. Can you please rewrite the above line so only one ListView column is created rather than three? I want to see how this is done because I have many code lines like this.

When the strategy does not compute the "By Symbol" tab it executes in less than a second--extremely fast. So it's not really a caching problem. It has something to do with creating too many extraneous ListView (C# collection) columns.

Is there a nice way of creating a
CODE:
Please log in to see this code.
C# code block so the DataSeries destructor is automatically called for all these intermediate DataSeries that get created along the way? Can you point me to a simple example doing this?
profile picture

Eugene

#4
QUOTE:
Is every DataSeries created (even with the "new" operator) going to be added to a ListView "C# collection"?

Yes, this is by design of the By Symbol tab. Like it or not, the idea here is to automatically display all the final values of each DataSeries created by the strategy (with some exceptions as per the Wealth-Lab User Guide).

QUOTE:
If so, is there a way to prevent this?

Yes, by unchecking the visualizer.

QUOTE:
It has something to do with creating too many extraneous ListView (C# collection) columns.

That's right. This is what I said in my reply above. Bars.Cache.Clear will not have directly affect the ListView; I mentioned it as a general workaround to improve memory usage.

QUOTE:
Can you please rewrite the above line so only one ListView column is created rather than three?

It's not possible to do what you're asking for neither here nor in Analysis Series (which is similar in this regard). All series are taken directly from Bars.Cache as is. No one is special.

You're welcome to develop your own performance visualizer that behaves the way you like it to:

Performance Visualizers

QUOTE:
C# code block so the DataSeries destructor is automatically called for all these intermediate DataSeries that get created along the way? Can you point me to a simple example doing this?

Destructors are not supported in WealthScript. Furthermore, they will crash Wealth-Lab if used.
profile picture

superticker

#5
Thanks for your quick reply. Your answers have been insightful. Obviously, I don't understand this framework too well. :(

QUOTE:
Is every DataSeries created going to be added to a ListView "C# collection"?
QUOTE:
Yes, this is by design of the By-Symbol tab.

What about any DataSeries that is created by compiled indicator code in a DLL object? Would the internal (and temporary) DataSeries within the DLL indicator be hidden from the default By-Symbol visualizer?

QUOTE:
It's not possible to [selectively omit some DataSeries from the By-Symbol visualizer.] ... No one is special.
It would be a nice enhancement to add a "visible flag" to the DataSeries constructor that would direct the By-Symbol visualizer to include or exclude that DataSeries in ListView column collections.

I appreciate your sentiment that I can override the existing DataSeries constructor and By-Symbol visualizer to do this myself. That's an interesting thought. But I would prefer to focus on developing my strategies rather than extending the Wealth-Lab framework. Also, I'm not personally that familiar with the DataSeries constructor; otherwise, I might consider doing this eventually.

Is it possible to selectively clear specific (temporary) DataSeries from the cache or is clearing an all or nothing proposition?

QUOTE:
Destructors are not supported in WealthScript. Furthermore, they will crash Wealth-Lab if used.

Is that because the Wealth-Lab's cache management system won't let .NET's garbage collection update reference pointers into dynamic storage (heap) correctly?

Wealth-Lab's caching system does have some real advantages over using the dynamic storage facility. For example, the time-of-life (ToL) of semi-permanent DataSeries objects can be extended long after the strategy code exits via the "global" cache--a great feature between runs and framework modules. However, for temporary DataSeries objects that are useless after the strategy code exits, having a destructor to release that memory upon exit would be best. Please fix dynamic memory management so destructors work as expected.
profile picture

Eugene

#6
QUOTE:
What about any DataSeries that is created by compiled indicator code in a DLL object? Would the internal (and temporary) DataSeries within the DLL indicator be hidden from the default By-Symbol visualizer?

No, it wouldn't (see the User Guide for two exceptions).

QUOTE:
It would be a nice enhancement to add a "visible flag" to the DataSeries constructor

It is much simpler to create your DataSeries as instructed by the UG to avoid being visible to the visualizer:

CODE:
Please log in to see this code.


QUOTE:
Is that because the Wealth-Lab's cache management system won't let .NET's garbage collection update reference pointers into dynamic storage (heap) correctly?

I'm in no position to answer that. To clarify my reply, I was talking about the Strategy class destructor (not DataSeries).
profile picture

superticker

#7
QUOTE:
... simpler to create your DataSeries as instructed by the UG to avoid being visible to the visualizer:

CODE:
Please log in to see this code.

I initially misunderstood you. I thought you said all DataSeries (cached or not) were placed in a ViewList collection.

You're saying if the "new" operator is used to locally create the DataSeries (so it's not cached), then it won't be visible by the By-Symbol visualizer? If so, then that works for me. :)

So if DataSeries arrays created with the "new" operator are not cached, then they must be stored in dynamic memory (heap), correct? If so, then their destructor is called when exiting the strategy so they will not be visible to the By-Symbol performance visualizer, correct?

Yes, I thought you meant the DataSeries destructor earlier, rather than the Strategy class destructor. Thanks for clarifying things.
profile picture

Eugene

#8
QUOTE:
So if DataSeries arrays created with the "new" operator are not cached, then they must be stored in dynamic memory (heap), correct? If so, then their destructor is called when exiting the strategy so they will not be visible to the By-Symbol performance visualizer, correct?

Yes, they will not be visible to the By-Symbol PV because the "new" operator won't cache them.
This website uses cookies to improve your experience. We'll assume you're ok with that, but you can opt-out if you wish (Read more).