You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
When reinitializing the Simulator repeatedly, e.g., in a Reinforcement Learning (RL) setting, memory growth can be observed. Please find different fixes below (this is not a Pull Request due to the last item in the list).
To reproduce
ReactionWheelStateEffector Memory Leak
In addition to issue #441, the destructor ReactionWheelStateEffector::~ReactionWheelStateEffector() in src/simulation/dynamics/reactionWheels/reactionWheelStateEffector.cpp uses free() on a data structure allocated with new. Additionally, it may be helpful to delete the elements of rwOutMsgs:
ReactionWheelStateEffector::~ReactionWheelStateEffector()
{
for (longunsignedint c = 0; c < this->rwOutMsgs.size(); c++) {
deletethis->rwOutMsgs.at(c);
}
for (longunsignedint c = 0; c < this->ReactionWheelData.size(); c++) {
deletethis->ReactionWheelData.at(c);
}
}
Missing Py_DECREF in SWIG Eigen Type Map
There are missing Py_DECREF in src/architecture/_GeneralModuleFiles/swig_eigen.i in the fragment checkPyObjectIsMatrixLike. The changes are annotated with new decrement.
%fragment("checkPyObjectIsMatrixLike", "header", fragment="getInputSize") {
/*This method returns an empty optional only if the given input is like the template type T.Otherwise, the returned optional contains a relevant error message.The size of the input is compared to the expected size of T (where dynamicallysized matrix T allow any number of rows/columns). Moreover, an error is raised forragged nested sequences (rows with different numbers of elements).*/template<classT>
std::optional<std::string> checkPyObjectIsMatrixLike(PyObject *input)
{
auto maybeSize = getInputSize(input);
if (!maybeSize)
{
return"Input is not a sequence";
}
auto [numberRows, numberColumns] = maybeSize.value();
if (T::RowsAtCompileTime != -1 && T::RowsAtCompileTime != numberRows)
{
std::string errorMsg = "Input does not have the correct number of rows. Expected "
+ std::to_string(T::RowsAtCompileTime) + " but found " + std::to_string(numberRows);
return errorMsg;
}
if (T::ColsAtCompileTime != -1 && T::ColsAtCompileTime != numberColumns)
{
std::string errorMsg = "Input does not have the correct number of columns. Expected "
+ std::to_string(T::ColsAtCompileTime) + " but found " + std::to_string(numberColumns);
return errorMsg;
}
for(Py_ssize_t row=0; row<numberRows; row++)
{
PyObject *rowPyObj = PySequence_GetItem(input, row);
Py_ssize_t localNumberColumns = PySequence_Check(rowPyObj) ? PySequence_Length(rowPyObj) : 1;
if (localNumberColumns != numberColumns)
{
Py_DECREF(rowPyObj); // new decrementreturn"All rows must be the same length! Row " + std::to_string(row) + " is not.";
}
Py_DECREF(rowPyObj); // new decrement
}
return {};
}
}
Check for Msg disown()
It may be of interest to verify whether <type>Msg.this.disown() is necessary in:
src/utilities/fswSetupRW.py (writeConfigMessage(), rwConfigMsg.this.disown(), line 87)
src/utilities/simIncludeRW.py (getConfigMessage(self), rwConfigMsg.this.disown(), line 379)
Expected behavior
With these changes, memory growth became unnoticeable for us even after millions of iterations.
The text was updated successfully, but these errors were encountered:
Howdy @KD-92 , thanks for the feedback. Something to look at in more detail. Regarding item 3., the reason we use disown() in the factory classes to ensure that the message memory is not released after being created in a sub-routine. There are likely better ways to do this that avoids creating msg objects which never get released
I think the conflict between to disown() or not to disown() is related to #676 . Developing a proper fix for that bug would allow the lifetime of the msg objects to be properly handled, instead of having to choose between mistakenly garbage collected in some situations vs intentionally leaked in all situations.
Describe the bug
When reinitializing the Simulator repeatedly, e.g., in a Reinforcement Learning (RL) setting, memory growth can be observed. Please find different fixes below (this is not a Pull Request due to the last item in the list).
To reproduce
In addition to issue #441, the destructor
ReactionWheelStateEffector::~ReactionWheelStateEffector()
insrc/simulation/dynamics/reactionWheels/reactionWheelStateEffector.cpp
usesfree()
on a data structure allocated withnew
. Additionally, it may be helpful to delete the elements ofrwOutMsgs
:Py_DECREF
in SWIG Eigen Type MapThere are missing
Py_DECREF
insrc/architecture/_GeneralModuleFiles/swig_eigen.i
in the fragmentcheckPyObjectIsMatrixLike
. The changes are annotated withnew decrement
.Msg disown()
It may be of interest to verify whether
<type>Msg.this.disown()
is necessary in:Expected behavior
With these changes, memory growth became unnoticeable for us even after millions of iterations.
The text was updated successfully, but these errors were encountered: