diff --git a/native/cocos/bindings/jswrapper/v8/Object.cpp b/native/cocos/bindings/jswrapper/v8/Object.cpp index 92b0424c9ca..a7a094705a7 100644 --- a/native/cocos/bindings/jswrapper/v8/Object.cpp +++ b/native/cocos/bindings/jswrapper/v8/Object.cpp @@ -401,13 +401,18 @@ Object *Object::createJSONObject(const ccstd::string &jsonStr) { } Object *Object::createJSONObject(std::u16string &&jsonStr) { - auto v8Str = v8::String::NewExternalTwoByte(__isolate, ccnew internal::ExternalStringResource(std::move(jsonStr))); + auto *external = ccnew internal::ExternalStringResource(std::move(jsonStr)); + auto v8Str = v8::String::NewExternalTwoByte(__isolate, external); if (v8Str.IsEmpty()) { return nullptr; } v8::Local context = __isolate->GetCurrentContext(); v8::MaybeLocal ret = v8::JSON::Parse(context, v8Str.ToLocalChecked()); + + // After v8::JSON::Parse, the memory of u16string could be freed. + external->freeMemory(); + if (ret.IsEmpty()) { return nullptr; } diff --git a/native/cocos/bindings/jswrapper/v8/Utils.cpp b/native/cocos/bindings/jswrapper/v8/Utils.cpp index 6e5334253fa..a2f7cd4f82c 100644 --- a/native/cocos/bindings/jswrapper/v8/Utils.cpp +++ b/native/cocos/bindings/jswrapper/v8/Utils.cpp @@ -243,6 +243,28 @@ void clearPrivate(v8::Isolate *isolate, ObjectWrap &wrap) { } } +// ExternalStringResource +ExternalStringResource::ExternalStringResource(std::u16string &&s) +: _s(std::move(s)) { +} + +const uint16_t* ExternalStringResource::data() const { + return reinterpret_cast(_s.data()); +} + +size_t ExternalStringResource::length() const { + return _s.length(); +} + +void ExternalStringResource::Dispose() { + delete this; +} + +void ExternalStringResource::freeMemory() { + _s.clear(); + _s.shrink_to_fit(); +} + } // namespace internal } // namespace se diff --git a/native/cocos/bindings/jswrapper/v8/Utils.h b/native/cocos/bindings/jswrapper/v8/Utils.h index a906862ed3c..3528057be42 100644 --- a/native/cocos/bindings/jswrapper/v8/Utils.h +++ b/native/cocos/bindings/jswrapper/v8/Utils.h @@ -52,24 +52,15 @@ void clearPrivate(v8::Isolate *isolate, ObjectWrap &wrap); class ExternalStringResource : public v8::String::ExternalStringResource { public: - explicit ExternalStringResource(std::u16string &&s) - : _s(std::move(s)) { - - } - + explicit ExternalStringResource(std::u16string &&s); ~ExternalStringResource() override = default; - const uint16_t* data() const override { - return reinterpret_cast(_s.data()); - } + const uint16_t* data() const override; + size_t length() const override; + void Dispose() override; + + void freeMemory(); - size_t length() const override { - return _s.length(); - } - - void Dispose() override { - delete this; - } private: std::u16string _s; };