cocos2dx 3.5 beta0 Mesh循环引用,造成析构时在AutoReleasePool中有多个引用残留

引擎版本 cocos2dx 3.5 beta0

写了个程序,发现每秒增加1MB的内存,最后定位在Mesh::create上

Mesh* Mesh::create(const std::vector& vertices, int perVertexSizeInFloat, const IndexArray& indices, const std::vector& attribs)
{
MeshData meshdata;
meshdata.attribs = attribs;
meshdata.vertex = vertices;
meshdata.subMeshIndices.push_back(indices);
meshdata.subMeshIds.push_back("");

auto meshvertexdata = MeshVertexData::create(meshdata);
auto indexData = meshvertexdata->getMeshIndexDataByIndex(0);

return create("", indexData);

}

继续看MeshVertexData::create()

MeshVertexData* MeshVertexData::create(const MeshData& meshdata)
{
auto vertexdata = new (std::nothrow) MeshVertexData();
int pervertexsize = meshdata.getPerVertexSize();
vertexdata->_vertexBuffer = VertexBuffer::create(pervertexsize, (int)(meshdata.vertex.size() / (pervertexsize / 4)));
vertexdata->_vertexData = VertexData::create();
CC_SAFE_RETAIN(vertexdata->_vertexData);
CC_SAFE_RETAIN(vertexdata->_vertexBuffer);

int offset = 0;
for (const auto& it : meshdata.attribs) {
    vertexdata->_vertexData->setStream(vertexdata->_vertexBuffer, VertexStreamAttribute(offset, it.vertexAttrib, it.type, it.size));
    offset += it.attribSizeBytes;
}

vertexdata->_attribs = meshdata.attribs;

if(vertexdata->_vertexBuffer)
{
    vertexdata->_vertexBuffer->updateVertices((void*)&meshdata.vertex, (int)meshdata.vertex.size() * 4 / vertexdata->_vertexBuffer->getSizePerVertex(), 0);
}

bool needCalcAABB = (meshdata.subMeshAABB.size() != meshdata.subMeshIndices.size());
for (size_t i = 0; i < meshdata.subMeshIndices.size(); i++) {


    auto& index = meshdata.subMeshIndices;
    auto indexBuffer = IndexBuffer::create(IndexBuffer::IndexType::INDEX_TYPE_SHORT_16, (int)(index.size()));
    indexBuffer->updateIndices(&index, (int)index.size(), 0);
  •    std::string id = (i < meshdata.subMeshIds.size() ? meshdata.subMeshIds : "");
      MeshIndexData* indexdata = nullptr;
      if (needCalcAABB)
      {
          auto aabb = Bundle3D::calculateAABB(meshdata.vertex, meshdata.getPerVertexSize(), index);
    

    indexdata = MeshIndexData::create(id, vertexdata, indexBuffer, aabb);
    }
    else
    indexdata = MeshIndexData::create(id, vertexdata, indexBuffer, meshdata.subMeshAABB*);

vertexdata->_indexs.pushBack(indexdata);*
}

vertexdata->autorelease();
return vertexdata;

}

继续看 MeshIndexData::create()

MeshIndexData* MeshIndexData::create(const std::string& id, MeshVertexData* vertexData, IndexBuffer* indexbuffer, const AABB& aabb)
{
auto meshindex = new (std::nothrow) MeshIndexData();

meshindex->_id = id;
meshindex->_indexBuffer = indexbuffer;
meshindex->_vertexData = vertexData;
indexbuffer->retain();

vertexData->retain();
meshindex->_aabb = aabb;

meshindex->autorelease();
return meshindex;

}

凌晨3点半了,脑子有点昏了,这里貌似有问题把?
这里循环引用了吧? (MeshVertexData *)vertexData 被 (MeshIndexData *)indexdata 引用,完了以后,(MeshIndexData *)indexdata 由被塞到 (MeshVertexData *)vertexData 的 Vector里去了,这是个cocos2dx的Vector,自带retain
……
于是…… 这是循环引用了吧,应该是无论如何这2个家伙都不会自动析构了,永远的留在AutoReleasePool里面了,直到Pool终结的那一天,所以程序本身也不会有Memory Leak

麻烦大家看下

头晕,别是看错了。。。
*

谢谢。好像是这个问题。3.6会修正这个问题。

3.6 ??!!! 3.5的日程表 本来是3月会有2次更新的,结果目前还是beta0 , 3.6啥时候才会出啊…… 先赶紧把3.5的更新放出来吧

Particle3D也肯定有内存不释放的问题,我还在查

Mesh这个终于搞定了

3.6 已修复

在3.9上测捕鱼达人那个漩涡的例子,但始终莫名崩溃,跟了下代码看到了和楼主所说问题相同的位置。3.9中虽然已经没有那个循环引用的问题,但是create的出来的mesh对象中的_vertexData referencecount始终是1,还是个autorelease的,也就是下一帧就被释放了。造成那个例子始终是崩溃的,不知道是不是还有其他用法。