Random crash on Android after removeUnusedTextures

Hi all!

I’m currently working on a quite large project with Cocos2d-X 3.7.1. To reduce RAM usage I’m using a loading scene to release unused resources before creating any game scene.
To release unused resources I’m using:

SpriteFrameCache::getInstance()->removeUnusedSpriteFrames();
Director::getInstance()->getTextureCache()->removeUnusedTextures();

By doing so I’m experiencing random crashes on Android and, as far as I tested, on my Samsung Galaxy S4. Here’s a partial stack trace:

std::pair<std::string const, cocos2d::Value>, std::allocator<std::pair<std::string const, cocos2d::Value> >, std::__detail::_Select1st, std::equal_to<std::string>, std::hash<std::string>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_find_node(unsigned int, std::string const&, u
I/DEBUG   (  301):     #02 pc 009ceb58  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (std::__detail::_Map_base<std::string, std::pair<std::string const, cocos2d::Value>, std::allocator<std::pair<std::string const, cocos2d::Value> >, std::__detail::_Select1st, std::equal_to<std::string>, std::hash<std::string>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>::operator[](std::string const&)+88)
I/DEBUG   (  301):     #03 pc 009ce704  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (std::unordered_map<std::string, cocos2d::Value, std::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, cocos2d::Value> > >::operator[](std::string const&)+32)
I/DEBUG   (  301):     #04 pc 0109d120  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (cocos2d::DictMaker::endElement(void*, char const*)+556)
I/DEBUG   (  301):     #05 pc 010b5364  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (cocos2d::SAXParser::endElement(void*, unsigned char const*)+60)
I/DEBUG   (  301):     #06 pc 010b5044  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (cocos2d::XmlSaxHander::VisitExit(tinyxml2::XMLElement const&)+52)
I/DEBUG   (  301):     #07 pc 011f88b4  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (tinyxml2::XMLElement::Accept(tinyxml2::XMLVisitor*) const+196)
I/DEBUG   (  301):     #08 pc 011f5710  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (tinyxml2::XMLDocument::Accept(tinyxml2::XMLVisitor*) const+108)
I/DEBUG   (  301):     #09 pc 010b51ac  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (cocos2d::SAXParser::parse(char const*, unsigned int)+108)
I/DEBUG   (  301):     #10 pc 0109c3f4  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (cocos2d::DictMaker::dictionaryWithDataOfFile(char const*, int)+324)
I/DEBUG   (  301):     #11 pc 0109da90  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (cocos2d::FileUtils::getValueMapFromData(char const*, int)+64)
I/DEBUG   (  301):     #12 pc 01067410  /data/app/com.mycompany.myapp-1/lib/arm/libcocos2dcpp.so (cocos2d::SpriteFrameCache::addSpriteFramesWithFileContent(std::string const&, cocos2d::Texture2D*)+92)

I cannot update the framework to the last version at the current stage of development to check if the problem has already been fixed, and I couldn’t been able to reproduce the problem on a clean new project, probably because of other complexities the my project has (expansion files, LevelHelper 2 Pro, …).

Anyway, by supposing that the creation of the new scene had some concurrency issue with the removal of the unused resources, I have tried a workaround, by adding a delay (1 second) between releasing the unused resources and creating the new scene. The problem seems solved on my test device, but obviously it is neither a safe nor a clean solution.

Any idea or better solution?

Where are you calling those functions? Is it on a different thread?

I’m calling them on cocos thread.

By now I updated the cocos framework version but the development phase has gone on, so it would be hard to reproduce the problem on this new version of cocos to see if the issue still persists.
Besides, adding a 1 second delay proved to be a stable solution, so I didn’t study the issue further.

My only conjecture is that it could have been due to the patch I did on FileUtilsAndroid to work with expansion files as suggested in this thread. Perhaps I did something wrong and caused a concurrency issue of some sort…