# garbage collection different between petsc4py 3.17.4 and 3.18.3

`petsc4py`

3.18.3 does not garbage collect as effectively as 3.17.4.

This plot shows memory usage when repeatedly creating and solving a matrix:

This has been observed on macOS, Debian, and Ubuntu.

In both cases, petsc4py was obtained from conda-forge.

This plot was generated by running `mprof`

on the following script in serial (adapted from demo/kspsolve):

```
from petsc4py import PETSc
def mat_and_vec():
# grid size and spacing
m, n = 32, 32
hx = 1.0/(m-1)
hy = 1.0/(n-1)
# create sparse matrix
A = PETSc.Mat()
A.create(PETSc.COMM_WORLD)
A.setSizes([m*n, m*n])
A.setType('aij') # sparse
A.setPreallocationNNZ(5)
# precompute values for setting
# diagonal and non-diagonal entries
diagv = 2.0/hx**2 + 2.0/hy**2
offdx = -1.0/hx**2
offdy = -1.0/hy**2
# loop over owned block of rows on this
# processor and insert entry values
Istart, Iend = A.getOwnershipRange()
for I in range(Istart, Iend) :
A[I,I] = diagv
i = I//n # map row number to
j = I - i*n # grid coordinates
if i> 0 : J = I-n; A[I,J] = offdx
if i< m-1: J = I+n; A[I,J] = offdx
if j> 0 : J = I-1; A[I,J] = offdy
if j< n-1: J = I+1; A[I,J] = offdy
# communicate off-processor values
# and setup internal data structures
# for performing parallel operations
A.assemblyBegin()
A.assemblyEnd()
# obtain sol & rhs vectors
x, b = A.createVecs()
x.set(0)
b.set(1)
return A, x, b
def solve(A, x, b):
# create linear solver
ksp = PETSc.KSP()
ksp.create(PETSc.COMM_WORLD)
# use conjugate gradients
ksp.setType('cg')
# and incomplete Cholesky
ksp.getPC().setType('icc')
# and next solve
ksp.setOperators(A)
ksp.setFromOptions()
ksp.solve(b, x)
for sweep in range(50000):
solve(*mat_and_vec())
```

## Notes

- I am aware that it would be more efficient to retain and repopulate the matrix and vectors, but repeatedly destroying and creating them used to work.
- Manually calling
`ksp.destroy()`

,`A.destroy()`

,`x.destroy()`

, and`b.destroy()`

at the end of`solve()`

also resolves the issue, but automatic garbage collection used to work when these variables went out of scope. - Manually calling
`PETSc.garbage_cleanup()`

at each iteration also resolves the issue, but automatic garbage collection used to work. -
`-malloc_dump`

and`-malloc_view`

indicate no leak with either version. - #1291 may be related.