firedrakeproject/firedrake — pull request #224 by wence- (2014-04-02 08:55:42+00:00)
Title: Function space caching sub optimal

We currently cache function spaces so that when we ask for the same fs on the same mesh, we don't build it again.

However, this leads to growing memory usage (especially when running pytest). Imagine the following, slightly contrived, example:

```python
from firedrake import *

for i in range(100):
m = UnitSquareMesh(1, 1)
for j in range(6):
fs = FunctionSpace(m, 'DG', j)
```

This will populate the function space cache with 600 entries.

Once the mesh goes out of scope, however, we're never going to be able to pull a function space out of the cache (since part of the cache key is the mesh we built it on).

This suggests that what we ought to do is cache function space objects on the mesh they're built on. When the mesh goes out of scope, we know we can throw away the function space cache.

The only issue I see here is a massive circular dependency pain, since function spaces hold on to the mesh they were built on. We can't use weakrefs in the cache, because we want to keep the function space around while the mesh is still around. Similarly, we can't use weakrefs in the function space to point to the mesh because we need the mesh to be around when using bits of the function space.

Maybe just having circular references will be ok.