Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/xpcom/base/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 5 kB image not shown  

Quelle  AvailableMemoryWatcher.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "AvailableMemoryWatcher.h"

#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/glean/XpcomMetrics.h"
#include "nsExceptionHandler.h"
#include "nsMemoryPressure.h"
#include "nsXULAppAPI.h"

namespace mozilla {

// Use this class as the initial value of
// nsAvailableMemoryWatcherBase::mCallback until RegisterCallback() is called
// so that nsAvailableMemoryWatcherBase does not have to check if its callback
// object is valid or not.
class NullTabUnloader final : public nsITabUnloader {
  ~NullTabUnloader() = default;

 public:
  NullTabUnloader() = default;

  NS_DECL_ISUPPORTS
  NS_DECL_NSITABUNLOADER
};

NS_IMPL_ISUPPORTS(NullTabUnloader, nsITabUnloader)

NS_IMETHODIMP NullTabUnloader::UnloadTabAsync() {
  return NS_ERROR_NOT_IMPLEMENTED;
}

StaticRefPtr<nsAvailableMemoryWatcherBase>
    nsAvailableMemoryWatcherBase::sSingleton;

/*static*/
already_AddRefed<nsAvailableMemoryWatcherBase>
nsAvailableMemoryWatcherBase::GetSingleton() {
  if (!sSingleton) {
    sSingleton = CreateAvailableMemoryWatcher();
    ClearOnShutdown(&sSingleton);
  }

  return do_AddRef(sSingleton);
}

NS_IMPL_ISUPPORTS(nsAvailableMemoryWatcherBase, nsIAvailableMemoryWatcherBase);

nsAvailableMemoryWatcherBase::nsAvailableMemoryWatcherBase()
    : mMutex("nsAvailableMemoryWatcher mutex"),
      mNumOfTabUnloading(0),
      mNumOfMemoryPressure(0),
      mTabUnloader(new NullTabUnloader),
      mInteracting(false) {
  MOZ_ASSERT(XRE_IsParentProcess(),
             "Watching memory only in the main process.");
}

const charconst nsAvailableMemoryWatcherBase::kObserverTopics[] = {
    // Use this shutdown phase to make sure the instance is destroyed in GTest
    "xpcom-shutdown",
    "user-interaction-active",
    "user-interaction-inactive",
};

nsresult nsAvailableMemoryWatcherBase::Init() {
  MOZ_ASSERT(NS_IsMainThread(),
             "nsAvailableMemoryWatcherBase needs to be initialized "
             "in the main thread.");

  if (mObserverSvc) {
    return NS_ERROR_ALREADY_INITIALIZED;
  }

  mObserverSvc = services::GetObserverService();
  MOZ_ASSERT(mObserverSvc);

  for (auto topic : kObserverTopics) {
    nsresult rv = mObserverSvc->AddObserver(this, topic,
                                            /* ownsWeak */ false);
    NS_ENSURE_SUCCESS(rv, rv);
  }
  return NS_OK;
}

void nsAvailableMemoryWatcherBase::Shutdown() {
  for (auto topic : kObserverTopics) {
    mObserverSvc->RemoveObserver(this, topic);
  }
}

NS_IMETHODIMP
nsAvailableMemoryWatcherBase::Observe(nsISupports* aSubject, const char* aTopic,
                                      const char16_t* aData) {
  MOZ_ASSERT(NS_IsMainThread());

  if (strcmp(aTopic, "xpcom-shutdown") == 0) {
    Shutdown();
  } else if (strcmp(aTopic, "user-interaction-inactive") == 0) {
    mInteracting = false;
#ifdef MOZ_CRASHREPORTER
    CrashReporter::SetInactiveStateStart();
#endif
  } else if (strcmp(aTopic, "user-interaction-active") == 0) {
    mInteracting = true;
#ifdef MOZ_CRASHREPORTER
    CrashReporter::ClearInactiveStateStart();
#endif
  }
  return NS_OK;
}

nsresult nsAvailableMemoryWatcherBase::RegisterTabUnloader(
    nsITabUnloader* aTabUnloader) {
  mTabUnloader = aTabUnloader;
  return NS_OK;
}

// This method is called as a part of UnloadTabAsync(). Like Notify(), if we
// call this method synchronously without releasing the lock first we can lead
// to deadlock.
nsresult nsAvailableMemoryWatcherBase::OnUnloadAttemptCompleted(
    nsresult aResult) {
  MutexAutoLock lock(mMutex);
  switch (aResult) {
    // A tab was unloaded successfully.
    case NS_OK:
      ++mNumOfTabUnloading;
      break;

    // There was no unloadable tab.
    case NS_ERROR_NOT_AVAILABLE:
      ++mNumOfMemoryPressure;
      NS_NotifyOfEventualMemoryPressure(MemoryPressureState::LowMemory);
      break;

    // There was a pending task to unload a tab.
    case NS_ERROR_ABORT:
      break;

    default:
      MOZ_ASSERT_UNREACHABLE("Unexpected aResult");
      break;
  }
  return NS_OK;
}

void nsAvailableMemoryWatcherBase::UpdateLowMemoryTimeStamp() {
  if (mLowMemoryStart.IsNull()) {
    mLowMemoryStart = TimeStamp::NowLoRes();
  }
}

void nsAvailableMemoryWatcherBase::RecordTelemetryEventOnHighMemory(
    const MutexAutoLock&) {
  glean::memory_watcher::on_high_memory_stats.Record(
      Some(glean::memory_watcher::OnHighMemoryStatsExtra{
          Some(nsPrintfCString(
              "%u,%u,%f", mNumOfTabUnloading, mNumOfMemoryPressure,
              (TimeStamp::NowLoRes() - mLowMemoryStart).ToSeconds())),
      }));
  mNumOfTabUnloading = mNumOfMemoryPressure = 0;
  mLowMemoryStart = TimeStamp();
}

// Define the fallback method for a platform for which a platform-specific
// CreateAvailableMemoryWatcher() is not defined.
#if defined(ANDROID) || \
    !defined(XP_WIN) && !defined(XP_DARWIN) && !defined(XP_LINUX)
already_AddRefed<nsAvailableMemoryWatcherBase> CreateAvailableMemoryWatcher() {
  RefPtr instance(new nsAvailableMemoryWatcherBase);
  return do_AddRef(instance);
}
#endif

}  // namespace mozilla

93%


¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.