Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak with Apollo Client in react native on iOS #9079

Closed
otusweb opened this issue Nov 18, 2021 · 5 comments
Closed

Memory leak with Apollo Client in react native on iOS #9079

otusweb opened this issue Nov 18, 2021 · 5 comments

Comments

@otusweb
Copy link

otusweb commented Nov 18, 2021

Intended outcome:
Run the application without a quickly increasing memory footprint causing the OS to kill the app

Actual outcome:

The memory footprint of the app quickly grows until the system decides to kill the application. Looking at the profiling information from Instruments, it looks like little chunk of 112 bytes are being allocated quickly and causing the memory usage to spin out of control

How to reproduce the issue:

Code

Note i'm new to this codebase and while a little familiar with Apollo, i'm by no mean an advanced user :-) So feel free to let me know if you need more info.

In a react native app.

const logErrorLink = onError(({ graphQLErrors, networkError, operation }) => {
  reportError(
    new Error(`Error Apollo ${operation.operationName}`),
    (report) => {
      const _params = {
        data: {
          operationName: operation.operationName,
          extensions: operation.extensions,
          query: operation.query,
          variables: operation.variables,
          conext: operation.getContext(),
          graphQLErrors,
          networkError,
        } as any,
      };
      report.addMetadata('report', _params);
    }
  );

});

const withToken = setContext(async () => {
  const user = auth().currentUser;
  let token = '';
  try {
    if (user) {
      token = await user.getIdToken();
    }
  } catch (error) {
    consoleDebug('error la', error);
  }
  return { token, uid: user?.uid || '' };
});

const authMiddleware = new ApolloLink((operation, forward) => {
  const { token, uid } = operation.getContext();
  operation.setContext(() => ({
    headers: {
      ...createRequestParams(uid, 'apollo', operation.operationName),
      Authorization: token ? `Bearer ${token as string}` : '',
    },
  }));
  return forward(operation);
});

const retryLink = new RetryLink({
  delay: (retryNumber) => {
    const delay = Math.pow(2, retryNumber) * 300;
    const randomSum = delay * 0.2 * Math.random(); // 0-20% of the delay
    return delay + randomSum;
  },
  attempts: {
    max: 4,
    retryIf: async (error, operation) => {
      if (error.statusCode === 401) {
        const user = auth().currentUser;
        const { uid } = operation.getContext();
        let token = '';
        if (user) {
          token = await user.getIdToken(true);
          bugsnag.leaveBreadcrumb('new refreshToken apollo');
        }
        if (token) {
          operation.setContext({
            headers: {
              ...createRequestParams(uid, 'apollo', operation.operationName),
              Authorization: `Bearer ${token}`,
            },
          });
          return true;
        }
      }
      return true;
    },
  },
});
const link = ApolloLink.from([
  retryLink,
  logErrorLink,
  withToken,
  authMiddleware.concat(persistedQueriesLink.concat(httpLink)),
]);
const linkPayment = ApolloLink.from([
  retryLink,
  logErrorLink,
  withToken,
  authMiddleware.concat(persistedQueriesLink.concat(httpLinkPayment)),
]);

const client = new ApolloClient({
  cache: new InMemoryCache(),
  name: `mobile-${Platform.OS}`,
  version: DeviceInfo.getReadableVersion(),
  // link: concat(authMiddleware, httpLink)
  link,
});

async processUser(data: any) {
    try {
      await client.mutate({
        mutation: updateUserMutation,
        variables: {
          data,
        },
      });
    } catch (e) {
      console.log('NEw apollo user', e);
    }
  }

Update user mutation

mutation updateUser($data: Json!) {
  updateUser(data: $data)
}

Run the app from Xcode by selecting Product > Profile

Once the method processUser is called, the memory footprint start to grow and the app crashes within 30s to 1 minute.

The image below shows the allocation of those 112 bytes of memory chunk over 25 seconds until the app is killed
Screenshot 2021-11-18 at 15 06 32

Looking at where this memory is allocated shows the following stack trace (some are from different places, but 99% is from this place):

   0 libc++abi.dylib operator new(unsigned long)
   1 Choose void* std::__1::__libcpp_operator_new<unsigned long>(unsigned long) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/new:235
   2 Choose std::__1::__libcpp_allocate(unsigned long, unsigned long) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/new:261
   3 Choose std::__1::allocator<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*> >::allocate(unsigned long) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/memory:870
   4 Choose std::__1::allocator_traits<std::__1::allocator<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*> > >::allocate(std::__1::allocator<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*> >&, unsigned long) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/__memory/allocator_traits.h:260
   5 Choose std::__1::unique_ptr<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*>, std::__1::__hash_node_destructor<std::__1::allocator<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*> > > > std::__1::__hash_table<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, std::__1::__unordered_map_hasher<folly::dynamic, std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, folly::detail::DynamicHasher, folly::detail::DynamicKeyEqual, true>, std::__1::__unordered_map_equal<folly::dynamic, std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, folly::detail::DynamicKeyEqual, folly::detail::DynamicHasher, true>, std::__1::allocator<std::__1::__hash_value_type<folly::dynamic, folly::dynamic> > >::__construct_node<std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>, std::__1::tuple<> >(std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>&&, std::__1::tuple<>&&) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/__hash_table:2455
   6 Choose std::__1::pair<std::__1::__hash_iterator<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*>*>, bool> std::__1::__hash_table<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, std::__1::__unordered_map_hasher<folly::dynamic, std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, folly::detail::DynamicHasher, folly::detail::DynamicKeyEqual, true>, std::__1::__unordered_map_equal<folly::dynamic, std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, folly::detail::DynamicKeyEqual, folly::detail::DynamicHasher, true>, std::__1::allocator<std::__1::__hash_value_type<folly::dynamic, folly::dynamic> > >::__emplace_unique_impl<std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>, std::__1::tuple<> >(std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>&&, std::__1::tuple<>&&) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/__hash_table:2137
   7 Choose std::__1::pair<std::__1::__hash_iterator<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*>*>, bool> std::__1::__hash_table<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, std::__1::__unordered_map_hasher<folly::dynamic, std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, folly::detail::DynamicHasher, folly::detail::DynamicKeyEqual, true>, std::__1::__unordered_map_equal<folly::dynamic, std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, folly::detail::DynamicKeyEqual, folly::detail::DynamicHasher, true>, std::__1::allocator<std::__1::__hash_value_type<folly::dynamic, folly::dynamic> > >::__emplace_unique<std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>, std::__1::tuple<> >(std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>&&, std::__1::tuple<>&&) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/__hash_table:1096
   8 Choose std::__1::pair<std::__1::__hash_map_iterator<std::__1::__hash_iterator<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*>*> >, bool> std::__1::unordered_map<folly::dynamic, folly::dynamic, folly::detail::DynamicHasher, folly::detail::DynamicKeyEqual, std::__1::allocator<std::__1::pair<folly::dynamic const, folly::dynamic> > >::emplace<std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>, std::__1::tuple<> >(std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>&&, std::__1::tuple<>&&) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/unordered_map:1158
   9 Choose auto std::__1::pair<std::__1::__hash_map_iterator<std::__1::__hash_iterator<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*>*> >, bool> folly::f14::detail::F14BasicMap<folly::dynamic, folly::dynamic, folly::detail::DynamicHasher, folly::detail::DynamicKeyEqual, std::__1::allocator<std::__1::pair<folly::dynamic const, folly::dynamic> > >::emplace<std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>, std::__1::tuple<> >(std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>&&, std::__1::tuple<>&&)::'lambda'(auto&, auto&&...)::operator()<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>, std::__1::tuple<> >(auto&, auto&&...) const /Users/otusweb/Projects/AppChoose/ios/Pods/Headers/Public/RCT-Folly/folly/container/detail/F14MapFallback.h:215
  10 Choose _ZN5folly6detail22callWithKeyAndPairArgsINS_7dynamicES2_ZNS_3f146detail11F14BasicMapIS2_S2_NS0_13DynamicHasherENS0_15DynamicKeyEqualENSt3__19allocatorINS8_4pairIKS2_S2_EEEEE7emplaceIJRKNS8_21piecewise_construct_tENS8_5tupleIJRNS8_12basic_stringIcNS8_11char_traitsIcEENS9_IcEEEEEEENSJ_IJEEEEEENSA_INS8_19__hash_map_iteratorINS8_15__hash_iteratorIPNS8_11__hash_nodeINS8_17__hash_value_typeIS2_S2_EEPvEEEEEEbEEDpOT_EUlRT_DpOT0_E_SO_JSP_EJEEEDaOT1_RKT2_ONSJ_IJDpT3_EEEONSJ_IJDpT4_EEE /Users/otusweb/Projects/AppChoose/ios/Pods/Headers/Public/RCT-Folly/folly/container/detail/Util.h:125
  11 Choose _ZN5folly6detail20callWithExtractedKeyINS_7dynamicES2_NS_3f146detail11F14BasicMapIS2_S2_NS0_13DynamicHasherENS0_15DynamicKeyEqualENSt3__19allocatorINS8_4pairIKS2_S2_EEEEE11UsableAsKeyESD_ZNSE_7emplaceIJRKNS8_21piecewise_construct_tENS8_5tupleIJRNS8_12basic_stringIcNS8_11char_traitsIcEENS9_IcEEEEEEENSK_IJEEEEEENSA_INS8_19__hash_map_iteratorINS8_15__hash_iteratorIPNS8_11__hash_nodeINS8_17__hash_value_typeIS2_S2_EEPvEEEEEEbEEDpOT_EUlRT_DpOT0_E_SQ_JELi0EEEDaRT2_OT3_SH_ONSK_IJT4_EEEONSK_IJDpT5_EEE /Users/otusweb/Projects/AppChoose/ios/Pods/Headers/Public/RCT-Folly/folly/container/detail/Util.h:155
  12 Choose std::__1::pair<std::__1::__hash_map_iterator<std::__1::__hash_iterator<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*>*> >, bool> folly::f14::detail::F14BasicMap<folly::dynamic, folly::dynamic, folly::detail::DynamicHasher, folly::detail::DynamicKeyEqual, std::__1::allocator<std::__1::pair<folly::dynamic const, folly::dynamic> > >::emplace<std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>, std::__1::tuple<> >(std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>&&, std::__1::tuple<>&&) /Users/otusweb/Projects/AppChoose/ios/Pods/Headers/Public/RCT-Folly/folly/container/detail/F14MapFallback.h:203
  13 Choose std::__1::enable_if<folly::detail::EligibleForHeterogeneousInsert<folly::dynamic, folly::detail::DynamicHasher, folly::detail::DynamicKeyEqual, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>::value, std::__1::pair<std::__1::__hash_map_iterator<std::__1::__hash_iterator<std::__1::__hash_node<std::__1::__hash_value_type<folly::dynamic, folly::dynamic>, void*>*> >, bool> >::type folly::f14::detail::F14BasicMap<folly::dynamic, folly::dynamic, folly::detail::DynamicHasher, folly::detail::DynamicKeyEqual, std::__1::allocator<std::__1::pair<folly::dynamic const, folly::dynamic> > >::try_emplace<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) /Users/otusweb/Projects/AppChoose/ios/Pods/Headers/Public/RCT-Folly/folly/container/detail/F14MapFallback.h:268
  14 Choose std::__1::enable_if<folly::detail::EligibleForHeterogeneousInsert<folly::dynamic, folly::detail::DynamicHasher, folly::detail::DynamicKeyEqual, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>::value, folly::dynamic&>::type folly::f14::detail::F14BasicMap<folly::dynamic, folly::dynamic, folly::detail::DynamicHasher, folly::detail::DynamicKeyEqual, std::__1::allocator<std::__1::pair<folly::dynamic const, folly::dynamic> > >::operator[]<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) /Users/otusweb/Projects/AppChoose/ios/Pods/Headers/Public/RCT-Folly/folly/container/detail/F14MapFallback.h:356
  15 Choose std::__1::enable_if<!(std::is_convertible<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::__wrap_iter<folly::dynamic*> >::value), void>::type folly::dynamic::insert<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::nullptr_t>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::nullptr_t&&) /Users/otusweb/Projects/AppChoose/ios/Pods/Headers/Public/RCT-Folly/folly/dynamic-inl.h:834
  16 Choose facebook::jsi::dynamicFromValue(facebook::jsi::Runtime&, facebook::jsi::Value const&) /Users/otusweb/Projects/AppChoose/node_modules/react-native/ReactCommon/jsi/jsi/JSIDynamic.cpp:187
  17 Choose facebook::react::JSIExecutor::callNativeModules(facebook::jsi::Value const&, bool) /Users/otusweb/Projects/AppChoose/node_modules/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp:420
  18 Choose facebook::react::JSIExecutor::callFunction(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, folly::dynamic const&) /Users/otusweb/Projects/AppChoose/node_modules/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp:270
  19 Choose std::__1::__function::__value_func<void (facebook::react::JSExecutor*)>::operator()(facebook::react::JSExecutor*&&) const /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/functional:1885
  20 Choose std::__1::function<void (facebook::react::JSExecutor*)>::operator()(facebook::react::JSExecutor*) const /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/functional:2560
  21 Choose facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8::operator()() const /Users/otusweb/Projects/AppChoose/node_modules/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp:310
  22 Choose decltype(std::__1::forward<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8&>(fp)()) std::__1::__invoke<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8&>(facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8&) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/type_traits:3694
  23 Choose void std::__1::__invoke_void_return_wrapper<void, true>::__call<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8&>(facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8&) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/__functional_base:348
  24 Choose std::__1::__function::__alloc_func<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8, std::__1::allocator<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8>, void ()>::operator()() /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/functional:1558
  25 Choose std::__1::__function::__func<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8, std::__1::allocator<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8>, void ()>::operator()() /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/functional:1732
  26 Choose std::__1::__function::__value_func<void ()>::operator()() const /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/functional:1885
  27 Choose std::__1::function<void ()>::operator()() const /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/functional:2560
  28 Choose facebook::react::tryAndReturnError(std::__1::function<void ()> const&) /Users/otusweb/Projects/AppChoose/node_modules/react-native/React/CxxModule/RCTCxxUtils.mm:74
  29 Choose facebook::react::RCTMessageThread::tryFunc(std::__1::function<void ()> const&) /Users/otusweb/Projects/AppChoose/node_modules/react-native/React/CxxBridge/RCTMessageThread.mm:69
  30 Choose std::__1::__function::__value_func<void ()>::operator()() const /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/functional:1885
  31 Choose std::__1::function<void ()>::operator()() const /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.0.sdk/usr/include/c++/v1/functional:2560
  32 Choose invocation function for block in facebook::react::RCTMessageThread::runAsync(std::__1::function<void ()>) /Users/otusweb/Projects/AppChoose/node_modules/react-native/React/CxxBridge/RCTMessageThread.mm:45
  33 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__
  34 CoreFoundation __CFRunLoopDoBlocks
  35 CoreFoundation __CFRunLoopRun
  36 CoreFoundation CFRunLoopRunSpecific
  37 Choose +[RCTCxxBridge runRunLoop] /Users/otusweb/Projects/AppChoose/node_modules/react-native/React/CxxBridge/RCTCxxBridge.mm:367
  38 Foundation __NSThread__start__
  39 libsystem_pthread.dylib _pthread_start
  40 libsystem_pthread.dylib thread_start

Versions
System:
OS: macOS 11.6
Binaries:
Node: 16.11.1 - ~/.nvm/versions/node/v16.11.1/bin/node
Yarn: 1.22.17 - ~/.nvm/versions/node/v16.11.1/bin/yarn
npm: 7.24.2 - ~/Projects/AppChoose/node_modules/.bin/npm
Browsers:
Chrome: 95.0.4638.69
Safari: 15.0
npmPackages:
@apollo/client: 3.4.15 => 3.4.15

I also tried to downgrade to 3.4.0, with no luck

I'm unsure if this is related to #8903 or not

@otusweb
Copy link
Author

otusweb commented Nov 18, 2021

The example above is on a mutation, but it also happens on query


const linkPayment = ApolloLink.from([
  retryLink,
  logErrorLink,
  withToken,
  authMiddleware.concat(persistedQueriesLink.concat(httpLinkPayment)),
]);


const clientPayment = new ApolloClient({
  cache: new InMemoryCache(),
  name: `mobile-${Platform.OS}`,
  version: DeviceInfo.getReadableVersion(),
  // link: concat(authMiddleware, httpLink)
  link: linkPayment,
});


  async getUserBalance(): Promise<number> {
    try {
      const datadd = await clientPayment.query({
        query: userBalanceQuery,
      });
      return datadd.data.getUserBalance || 0;
    } catch (e) {
      return 0;
    }
  }

Once getUserBalance is called I get the same results.

@benjamn
Copy link
Member

benjamn commented Nov 22, 2021

@otusweb Just so everything's up-to-date, can you try updating to @apollo/[email protected]? Release notes here if you need them (especially the note about .cjs and React Native).

I have no real basis for this conjecture, but I have a hunch it may be time to retire the React Native exception for canUseWeakMap, which was necessary in the past because React Native's WeakMap implementation was unreliable/slow. If you want to try making that change locally (ignore navigator.product) and retest your memory consumption, that would save me cutting a one-off release for testing (which I'm also happy to do if that's easiest).

@otusweb
Copy link
Author

otusweb commented Nov 24, 2021

@benjamn I updated and tried changing
export var canUseWeakMap = typeof WeakMap === 'function' && !(typeof navigator === 'object' && navigator.product === 'ReactNative');
to
export var canUseWeakMap = typeof WeakMap === 'function' && !(typeof navigator === 'object');

Unfortunately, this did not solve our issue.

@otusweb
Copy link
Author

otusweb commented Nov 24, 2021

An extra piece of information is that it is only reproducible in release builds. The memory footprint is stable while using debug release.

@otusweb
Copy link
Author

otusweb commented Nov 26, 2021

Turns out this is not due to Apollo, but something we were doing in one of our middleware.

@otusweb otusweb closed this as completed Nov 26, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants