The problem here is with the anonymous MWArrays which you are creating to fill the struct array with. We will try to explain this graphically, but for this we slightly simplify the example: we use only one field: "Field1" and set KMAX = 1.
You start with creating the MWStructArray:
MWStructArraydata5 = new MWStructArray(1, KMAX, FIELDS);
You then call:
data5.set(FIELDS[0], k + 1, new MWNumericArray(k * 1.13));
Where the new MWNumericArray(k * 1.13) part creates a new anonymous MWNumericArray with an underlying native MATLAB array with the actual data:
And the set operation makes, in accordance to the documentation"If element is of type MWArray, the cell at index set to a shared copy of the underlying MATLAB array", Field1 point to the underlying native MATLAB array:
Then when your code continues, the anonymous array goes out of scope. However in Java going out of scope means that it gets marked for being disposed, it does not necessarily mean that the object is really deleted at that time; Java itself determines whether and when to run the object's finalizer.
It is important to note here that the Java Garbage Collector is not aware of the size of the Native MATLAB array to which the anonymous MWNumericArray is keeping a reference; it only sees the relatively small Java part of the MWNumericArray. This could lead to the Garbage Collector deciding to never release the anonymous MWNumericArray at all (i.e. it does not think it is worth the CPU cycles to clear the array which is using only a little amount of memory anyway).
So you will have a situation:
Then when you do specifically dispose of the MWStructArray with MWarray.disposeArray, data5 is really deleted and not only marked for deletion. This will also delete Field1 and its reference to the Native MATLAB Array, leaving:
But as you can see the anonymous MWNumericArray may still exist and if so, it does still have a reference to the Native MATLAB Array and as long as this is true, the Native MATLAB Array may not be deleted. This may lead to something which looks like a memory leak, but in fact it is not, it is how finalizers and garbage collection work in Java in combination with how MWArrays may have large underlying native data.
Now how to prevent this from happening?
There are two options:
Instead of using an anonymous array you can use a temporary named variable which you can specifically dispose:
MWNumericArraytemp = new MWNumericArray(k * 1.13);
data5.set(FIELDS[0], k + 1, temp);
MWArray.disposeArray(temp);
The following illustrations show what happens in this situation:
MWNumericArraytemp = new MWNumericArray(k * 1.13);
data5.set(FIELDS[0], k + 1, temp);
MWArray.disposeArray(temp);
If you then also call MWArray.disposeArray(data5); all references to the native MATLAB array are removed and then the native array will also be cleared immediately.
Or even easier: the set method directly accepts native Java datatypes:
data5.set(FIELDS[0], k + 1, k*1.13);
Which would basically directly create:
Where again MWArray.disposeArray(data5); would remove all references to the native array and clear it.