[Mono-dev] (no subject)

Roei Erez roeie at mainsoft.com
Thu Aug 30 10:24:33 EDT 2007


Hi all,

As a continue to the last discussion of cecil memory consumption, I am
attaching some changes that emphasize the concepts.

In order to remind everyone and to introduce the problem to the
'mono-cecil' group here is a summary:

 

We have noticed that cecil consume relatively a lot of memory.

This is due to the fact the code builds a full object model on top of
the assembly basic tables.

Many users are only interested in reading a part of the assembly;
therefore the full object model is sometimes redundant.

 

At the last discussion we were considering some options:

1.       Get rid of the basic tables after building the object model.

2.       Make the object model lazy, where the objects are accessing the
basic tables directly.

3.       Maybe expose a way to load an assembly in a read-only way,
which will make the implementation easier.

 

I have made some thinking (and coding) regarding the second option,
which I think is the right way to do it, and you can look at the
attached diff as a proposed design.

Here are some explanations about the code changes:

 

1.	A new class 'LazyReflectionReader' is introduced, which is
responsible for the lazy assembly reading. This class does not build all
the TypeDefinition, MethodDefinition, FieldDefinition ... objects at the
beginning, but only when they are accessed. It also provide some
internal helper methods for resolving the relations between elements,
for example 'GetDeclaringType(MetadataToken token)', which is used by
the lazy 'object model' classes. Currently not all fetching is lazy, but
you still can see the differences in terms of load time and memory
consumption.
2.	The object model instances that are instantiated by the
'LazyReflectionReader' are not populated with their entire dependencies
for example TypeDefinition is not populated with its Methods, instead
they are calling the helper methods in the 'LazyReflectionReader' in
order to resolve the dependencies on request.
3.	A new class 'MetadataRelations' is introduced which is used as a
preprocessor of the assembly, and creates the relations to be used by
the helper methods.
4.	I have added a method on AssemblyFactory class: 'GetAssembly
(string file, bool lazy)'.This method loads an assembly in a lazy way,
and I have added this method only for the purpose of playing with the
two implementations and see the differences, it is not part of the
design. 

 

Here are some design issues that I have encountered during my work:

1. Remove the sealed modifier from the object model classes (
TypeDefinition, FieldDefinition, MethodDefinition...   ) so we can
derive from them?

2. Exposing a way to plugin you own ReflectionReader, so the use can
implement his own object model loading?

 

This code is not tested, and is provided for design purpose.
Nevertheless you are welcome to measure the differences in loading time
and memory consumption between the lazy and not lazy load.

Any comments, remarks are very welcome.

 

Regares, 

Roei Erez

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20070830/8c64565f/attachment.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cecil_optimization.patch
Type: application/octet-stream
Size: 69537 bytes
Desc: cecil_optimization.patch
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20070830/8c64565f/attachment.obj 


More information about the Mono-devel-list mailing list