diff options
author | ssid <ssid@chromium.org> | 2015-10-12 10:49:03 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-12 17:49:46 +0000 |
commit | 9f8022f2aadfd86989231e6d367c2c2b9a53ae4b (patch) | |
tree | 7566cfd6b24a6087a535cc47d498114fba990669 /sql | |
parent | 55e0b3620524432d77cd3f707acd6ed470c2f1c9 (diff) | |
download | chromium_src-9f8022f2aadfd86989231e6d367c2c2b9a53ae4b.zip chromium_src-9f8022f2aadfd86989231e6d367c2c2b9a53ae4b.tar.gz chromium_src-9f8022f2aadfd86989231e6d367c2c2b9a53ae4b.tar.bz2 |
[tracing] Add sqlite memory statistics to tracing.
The process-wide memory usage statistics of sqlite library is added to
chrome://tracing. The memory usage of sqlite library is mainly through
sqlite_malloc. The total usage of the process is recorded by
sqlite3_memory_used() api. This CL also adds per-connection memory
usage to tracing. Each connection uses memory for cache, schema and
statement, and these usages are recorded. sqlit3_malloc uses malloc
internally to allocate memory. So, thie memory is traced as
sub-allocation from system_allocator(malloc).
This CL lets us keep track of sqlite memory usage in chrome telemetry.
BUG=466141
Review URL: https://codereview.chromium.org/1327063002
Cr-Commit-Position: refs/heads/master@{#353549}
Diffstat (limited to 'sql')
-rw-r--r-- | sql/BUILD.gn | 3 | ||||
-rw-r--r-- | sql/connection.cc | 44 | ||||
-rw-r--r-- | sql/connection.h | 10 | ||||
-rw-r--r-- | sql/connection_unittest.cc | 9 | ||||
-rw-r--r-- | sql/sql.gyp | 3 | ||||
-rw-r--r-- | sql/sql_memory_dump_provider.cc | 62 | ||||
-rw-r--r-- | sql/sql_memory_dump_provider.h | 36 | ||||
-rw-r--r-- | sql/sql_memory_dump_provider_unittest.cc | 22 |
8 files changed, 187 insertions, 2 deletions
diff --git a/sql/BUILD.gn b/sql/BUILD.gn index 57f1b38..8d071a3 100644 --- a/sql/BUILD.gn +++ b/sql/BUILD.gn @@ -15,6 +15,8 @@ component("sql") { "meta_table.h", "recovery.cc", "recovery.h", + "sql_memory_dump_provider.cc", + "sql_memory_dump_provider.h", "statement.cc", "statement.h", "transaction.cc", @@ -77,6 +79,7 @@ test("sql_unittests") { "connection_unittest.cc", "meta_table_unittest.cc", "recovery_unittest.cc", + "sql_memory_dump_provider_unittest.cc", "sqlite_features_unittest.cc", "statement_unittest.cc", "test/paths.cc", diff --git a/sql/connection.cc b/sql/connection.cc index 20f0f07..61aebbe 100644 --- a/sql/connection.cc +++ b/sql/connection.cc @@ -19,6 +19,8 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" +#include "base/trace_event/memory_dump_manager.h" +#include "base/trace_event/process_memory_dump.h" #include "sql/statement.h" #include "third_party/sqlite/sqlite3.h" @@ -217,6 +219,44 @@ bool Connection::ShouldIgnoreSqliteError(int error) { return current_ignorer_cb_->Run(error); } +bool Connection::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) { + if (args.level_of_detail == + base::trace_event::MemoryDumpLevelOfDetail::LIGHT || + !db_) { + return true; + } + + // The high water mark is not tracked for the following usages. + int cache_size, dummy_int; + sqlite3_db_status(db_, SQLITE_DBSTATUS_CACHE_USED, &cache_size, &dummy_int, + 0 /* resetFlag */); + int schema_size; + sqlite3_db_status(db_, SQLITE_DBSTATUS_SCHEMA_USED, &schema_size, &dummy_int, + 0 /* resetFlag */); + int statement_size; + sqlite3_db_status(db_, SQLITE_DBSTATUS_STMT_USED, &statement_size, &dummy_int, + 0 /* resetFlag */); + + std::string name = base::StringPrintf( + "sqlite/%s_connection/%p", + histogram_tag_.empty() ? "Unknown" : histogram_tag_.c_str(), this); + base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(name); + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + cache_size + schema_size + statement_size); + dump->AddScalar("cache_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + cache_size); + dump->AddScalar("schema_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + schema_size); + dump->AddScalar("statement_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + statement_size); + return true; +} + // static void Connection::SetErrorIgnorer(Connection::ErrorIgnorerCallback* cb) { CHECK(current_ignorer_cb_ == NULL); @@ -291,9 +331,13 @@ Connection::Connection() update_time_histogram_(NULL), query_time_histogram_(NULL), clock_(new TimeSource()) { + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( + this); } Connection::~Connection() { + base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( + this); Close(); } diff --git a/sql/connection.h b/sql/connection.h index d456b6c..7d2ab6a 100644 --- a/sql/connection.h +++ b/sql/connection.h @@ -18,6 +18,7 @@ #include "base/memory/scoped_ptr.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" +#include "base/trace_event/memory_dump_provider.h" #include "sql/sql_export.h" struct sqlite3; @@ -102,7 +103,7 @@ class SQL_EXPORT TimeSource { DISALLOW_COPY_AND_ASSIGN(TimeSource); }; -class SQL_EXPORT Connection { +class SQL_EXPORT Connection : public base::trace_event::MemoryDumpProvider { private: class StatementRef; // Forward declaration, see real one below. @@ -110,7 +111,7 @@ class SQL_EXPORT Connection { // The database is opened by calling Open[InMemory](). Any uncommitted // transactions will be rolled back when this object is deleted. Connection(); - ~Connection(); + ~Connection() override; // Pre-init configuration ---------------------------------------------------- @@ -464,6 +465,11 @@ class SQL_EXPORT Connection { // tests. static bool ShouldIgnoreSqliteError(int error); + // base::trace_event::MemoryDumpProvider implementation. + bool OnMemoryDump( + const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* process_memory_dump) override; + private: // For recovery module. friend class Recovery; diff --git a/sql/connection_unittest.cc b/sql/connection_unittest.cc index 0038a1d..d933a6d 100644 --- a/sql/connection_unittest.cc +++ b/sql/connection_unittest.cc @@ -11,6 +11,7 @@ #include "base/metrics/statistics_recorder.h" #include "base/strings/stringprintf.h" #include "base/test/histogram_tester.h" +#include "base/trace_event/process_memory_dump.h" #include "sql/connection.h" #include "sql/correct_sql_test_base.h" #include "sql/meta_table.h" @@ -1378,4 +1379,12 @@ TEST_F(SQLConnectionTest, MmapTest) { } #endif +TEST_F(SQLConnectionTest, OnMemoryDump) { + base::trace_event::ProcessMemoryDump pmd(nullptr); + base::trace_event::MemoryDumpArgs args = { + base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; + ASSERT_TRUE(db().OnMemoryDump(args, &pmd)); + EXPECT_GE(pmd.allocator_dumps().size(), 1u); +} + } // namespace diff --git a/sql/sql.gyp b/sql/sql.gyp index 115a93b..362597e 100644 --- a/sql/sql.gyp +++ b/sql/sql.gyp @@ -29,6 +29,8 @@ 'meta_table.h', 'recovery.cc', 'recovery.h', + 'sql_memory_dump_provider.cc', + 'sql_memory_dump_provider.h', 'statement.cc', 'statement.h', 'transaction.cc', @@ -89,6 +91,7 @@ 'connection_unittest.cc', 'meta_table_unittest.cc', 'recovery_unittest.cc', + 'sql_memory_dump_provider_unittest.cc', 'sqlite_features_unittest.cc', 'statement_unittest.cc', 'test/paths.cc', diff --git a/sql/sql_memory_dump_provider.cc b/sql/sql_memory_dump_provider.cc new file mode 100644 index 0000000..bb6d813 --- /dev/null +++ b/sql/sql_memory_dump_provider.cc @@ -0,0 +1,62 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sql/sql_memory_dump_provider.h" + +#include "base/trace_event/memory_dump_manager.h" +#include "base/trace_event/process_memory_dump.h" +#include "third_party/sqlite/sqlite3.h" + +namespace sql { + +// static +SqlMemoryDumpProvider* SqlMemoryDumpProvider::GetInstance() { + return base::Singleton< + SqlMemoryDumpProvider, + base::LeakySingletonTraits<SqlMemoryDumpProvider>>::get(); +} + +SqlMemoryDumpProvider::SqlMemoryDumpProvider() {} + +SqlMemoryDumpProvider::~SqlMemoryDumpProvider() {} + +bool SqlMemoryDumpProvider::OnMemoryDump( + const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) { + int memory_used = 0; + int memory_high_water = 0; + int status = sqlite3_status(SQLITE_STATUS_MEMORY_USED, &memory_used, + &memory_high_water, 1 /*resetFlag */); + if (status != SQLITE_OK) + return false; + + base::trace_event::MemoryAllocatorDump* dump = + pmd->CreateAllocatorDump("sqlite"); + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + memory_used); + dump->AddScalar("malloc_high_wmark_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + memory_high_water); + + int dummy_high_water = -1; + int malloc_count = -1; + status = sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &malloc_count, + &dummy_high_water, 0 /* resetFlag */); + if (status == SQLITE_OK) { + dump->AddScalar("malloc_count", + base::trace_event::MemoryAllocatorDump::kUnitsObjects, + malloc_count); + } + + const char* system_allocator_name = + base::trace_event::MemoryDumpManager::GetInstance() + ->system_allocator_pool_name(); + if (system_allocator_name) { + pmd->AddSuballocation(dump->guid(), system_allocator_name); + } + return true; +} + +} // namespace sql diff --git a/sql/sql_memory_dump_provider.h b/sql/sql_memory_dump_provider.h new file mode 100644 index 0000000..051755f --- /dev/null +++ b/sql/sql_memory_dump_provider.h @@ -0,0 +1,36 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SQL_PROCESS_MEMORY_DUMP_PROVIDER_H +#define SQL_PROCESS_MEMORY_DUMP_PROVIDER_H + +#include "base/memory/singleton.h" +#include "base/trace_event/memory_dump_provider.h" +#include "sql/sql_export.h" + +namespace sql { + +// Adds process-wide memory usage statistics about sqlite to chrome://tracing. +// sql::Connection::OnMemoryDump adds per-connection memory statistics. +class SQL_EXPORT SqlMemoryDumpProvider + : public base::trace_event::MemoryDumpProvider { + public: + static SqlMemoryDumpProvider* GetInstance(); + + // MemoryDumpProvider implementation. + bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) override; + + private: + friend struct base::DefaultSingletonTraits<SqlMemoryDumpProvider>; + + SqlMemoryDumpProvider(); + ~SqlMemoryDumpProvider() override; + + DISALLOW_COPY_AND_ASSIGN(SqlMemoryDumpProvider); +}; + +} // namespace sql + +#endif // SQL_PROCESS_MEMORY_DUMP_PROVIDER_H diff --git a/sql/sql_memory_dump_provider_unittest.cc b/sql/sql_memory_dump_provider_unittest.cc new file mode 100644 index 0000000..1f1dcf9 --- /dev/null +++ b/sql/sql_memory_dump_provider_unittest.cc @@ -0,0 +1,22 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sql/sql_memory_dump_provider.h" + +#include "base/trace_event/process_memory_dump.h" +#include "sql/test/sql_test_base.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +using SQLMemoryDumpProviderTest = sql::SQLTestBase; +} + +TEST_F(SQLMemoryDumpProviderTest, OnMemoryDump) { + base::trace_event::ProcessMemoryDump pmd(nullptr); + base::trace_event::MemoryDumpArgs args = { + base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; + ASSERT_TRUE( + sql::SqlMemoryDumpProvider::GetInstance()->OnMemoryDump(args, &pmd)); + ASSERT_TRUE(pmd.GetAllocatorDump("sqlite")); +} |