I use some data structures to store images of defective products in an inspection application. The data structure store defect information in defectDB_ and use a "url" point to imageDB_, which use std::vector to store actual image data. The problem is: I use imageDB_.erase() to erase the element, but the vector's memory is not released, the memory usage increased very fast. The following is "DB" definition:
// sourceId[0~3],defectRect,defectImageUrl,defectString
using DefectVector = std::vector<std::tuple<int, QRect, QString, QString>>;
//image(data,w,h,pitch,channel)
using ImageData = std::tuple<std::vector<uchar>, int, int, int, int>;
// productId:defectVector
std::map<int,DefectVector> defectDB_;
// imageUrl:
std::map<QString,ImageData> imageDB_;
The following codes store some images into memory. The std::vector is used to store the actual image data.
if (!thumb.isNull())
{
QString key = QString("%1/%2/%3/%4").arg(id).arg(sourceId).arg(imageUrl).arg("thumb");
imageDB_[key] = std::make_tuple(std::vector<uchar>(), thumb.width(), thumb.height(), thumb.bytesPerLine(),
thumb.format() == QImage::Format_Grayscale8 ? 1 : 3);
// allocate a buffer
std::get<0>(imageDB_[key]).resize(thumb.height()*thumb.bytesPerLine());
// copy to the buffer
std::memcpy(std::get<0>(imageDB_[key]).data(), thumb.bits(), thumb.height()*thumb.bytesPerLine());
}
In the other place, I erased some items in imgeDB_ when there are too many images. The codes:
if (defectDB_.size() > MAX_DEFECTS_COUNT)
{
auto head = defectDB_.begin();
auto list = head->second;
for (auto t : list)
{
auto url = std::get<2>(t);
auto it = imageDB_.find(url);
if (it != imageDB_.end())
{
imageDB_.erase(it);
}
else {
qCritical() << "Missed image for image url:" << url;
}
}
defectDB_.erase(head);
}
It seems the memory allocated by
std::get<0>(imageDB_[key]).resize(thumb.height()*thumb.bytesPerLine());
is never released! Anyone can help me to figure it out?
Aucun commentaire:
Enregistrer un commentaire