Skip to content

Commit

Permalink
Instrument SpdySessionPool using MemoryDumpProvider
Browse files Browse the repository at this point in the history
This CL adds a DumpMemoryStats() method to SpdySessionPool and
SpdySession to track memory usage from active and idle socket.

BUG=669108

Review-Url: https://codereview.chromium.org/2565523002
Cr-Commit-Position: refs/heads/master@{#437356}
  • Loading branch information
xunjieli authored and Commit bot committed Dec 8, 2016
1 parent 926b579 commit 36fa039
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 0 deletions.
2 changes: 2 additions & 0 deletions net/http/http_network_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ void HttpNetworkSession::DumpMemoryStats(
http_network_session_dump = pmd->CreateAllocatorDump(name);
normal_socket_pool_manager_->DumpMemoryStats(
pmd, http_network_session_dump->absolute_name());
spdy_session_pool_.DumpMemoryStats(
pmd, http_network_session_dump->absolute_name());
pmd->AddOwnershipEdge(pmd->GetAllocatorDump(parent_absolute_name)->guid(),
http_network_session_dump->guid());
}
Expand Down
6 changes: 6 additions & 0 deletions net/socket/client_socket_handle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ bool ClientSocketHandle::GetLoadTimingInfo(
return true;
}

void ClientSocketHandle::DumpMemoryStats(
base::trace_event::ProcessMemoryDump* pmd,
const std::string& parent_absolute_name) const {
socket_->DumpMemoryStats(pmd, parent_absolute_name);
}

void ClientSocketHandle::SetSocket(std::unique_ptr<StreamSocket> s) {
socket_ = std::move(s);
}
Expand Down
11 changes: 11 additions & 0 deletions net/socket/client_socket_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
#include "net/socket/connection_attempts.h"
#include "net/socket/stream_socket.h"

namespace base {
namespace trace_event {
class ProcessMemoryDump;
}
}

namespace net {

// A container for a StreamSocket.
Expand Down Expand Up @@ -122,6 +128,11 @@ class NET_EXPORT ClientSocketHandle {
bool GetLoadTimingInfo(bool is_reused,
LoadTimingInfo* load_timing_info) const;

// Dumps memory allocation stats. |parent_dump_absolute_name| is the name
// used by the parent MemoryAllocatorDump in the memory dump hierarchy.
void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
const std::string& parent_dump_absolute_name) const;

// Used by ClientSocketPool to initialize the ClientSocketHandle.
//
// SetSocket() may also be used if this handle is used as simply for
Expand Down
13 changes: 13 additions & 0 deletions net/spdy/spdy_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "crypto/ec_private_key.h"
Expand Down Expand Up @@ -970,6 +972,17 @@ bool SpdySession::CloseOneIdleConnection() {
return false;
}

void SpdySession::DumpMemoryStats(
base::trace_event::ProcessMemoryDump* pmd,
const std::string& parent_absolute_name) const {
std::string name =
base::StringPrintf("%s/session_%p", parent_absolute_name.c_str(), this);
base::trace_event::MemoryAllocatorDump* session_dump =
pmd->CreateAllocatorDump(name);
session_dump->AddString("active", "", is_active() ? "1" : "0");
connection_->DumpMemoryStats(pmd, name);
}

void SpdySession::EnqueueStreamWrite(
const base::WeakPtr<SpdyStream>& stream,
SpdyFrameType frame_type,
Expand Down
11 changes: 11 additions & 0 deletions net/spdy/spdy_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@
#include "url/gurl.h"
#include "url/scheme_host_port.h"

namespace base {
namespace trace_event {
class ProcessMemoryDump;
}
}

namespace net {

namespace test {
Expand Down Expand Up @@ -565,6 +571,11 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// HigherLayeredPool implementation:
bool CloseOneIdleConnection() override;

// Dumps memory allocation stats. |parent_dump_absolute_name| is the name
// used by the parent MemoryAllocatorDump in the memory dump hierarchy.
void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
const std::string& parent_dump_absolute_name) const;

private:
friend class test::SpdyStreamTest;
friend class base::RefCounted<SpdySession>;
Expand Down
14 changes: 14 additions & 0 deletions net/spdy/spdy_session_pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include "base/metrics/histogram_macros.h"
#include "base/profiler/scoped_tracker.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "net/base/address_list.h"
Expand Down Expand Up @@ -363,6 +366,17 @@ void SpdySessionPool::OnCertDBChanged(const X509Certificate* cert) {
CloseCurrentSessions(ERR_CERT_DATABASE_CHANGED);
}

void SpdySessionPool::DumpMemoryStats(
base::trace_event::ProcessMemoryDump* pmd,
const std::string& parent_dump_absolute_name) const {
std::string dump_name = base::StringPrintf("%s/spdy_session_pool",
parent_dump_absolute_name.c_str());
pmd->CreateAllocatorDump(dump_name);
for (const auto& session : sessions_) {
session->DumpMemoryStats(pmd, dump_name);
}
}

bool SpdySessionPool::IsSessionAvailable(
const base::WeakPtr<SpdySession>& session) const {
for (AvailableSessionMap::const_iterator it = available_sessions_.begin();
Expand Down
9 changes: 9 additions & 0 deletions net/spdy/spdy_session_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
#include "net/spdy/spdy_session_key.h"
#include "net/ssl/ssl_config_service.h"

namespace base {
namespace trace_event {
class ProcessMemoryDump;
}
}

namespace net {

class ClientSocketHandle;
Expand Down Expand Up @@ -143,6 +149,9 @@ class NET_EXPORT SpdySessionPool
// is changed.
void OnCertDBChanged(const X509Certificate* cert) override;

void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
const std::string& parent_dump_absolute_name) const;

private:
friend class SpdySessionPoolPeer; // For testing.

Expand Down
57 changes: 57 additions & 0 deletions net/spdy/spdy_session_pool_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event_argument.h"
#include "net/dns/host_cache.h"
#include "net/http/http_network_session.h"
#include "net/log/net_log_with_source.h"
Expand Down Expand Up @@ -668,4 +671,58 @@ TEST_F(SpdySessionPoolTest, FindAvailableSession) {
spdy_session_pool_->CloseCurrentSessions(ERR_ABORTED);
}

TEST_F(SpdySessionPoolTest, DumpMemoryStats) {
SpdySessionKey key(HostPortPair("https://www.example.org", 443),
ProxyServer::Direct(), PRIVACY_MODE_DISABLED);

MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
session_deps_.socket_factory->AddSocketDataProvider(&data);

SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);

CreateNetworkSession();

base::WeakPtr<SpdySession> session =
CreateSecureSpdySession(http_session_.get(), key, NetLogWithSource());

// Flush the SpdySession::OnReadComplete() task.
base::RunLoop().RunUntilIdle();

EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key));
base::trace_event::MemoryDumpArgs dump_args = {
base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
new base::trace_event::ProcessMemoryDump(nullptr, dump_args));
base::trace_event::MemoryAllocatorDump* parent_dump =
process_memory_dump->CreateAllocatorDump("parent");
spdy_session_pool_->DumpMemoryStats(process_memory_dump.get(),
parent_dump->absolute_name());

// Whether SpdySession::DumpMemoryStats() is invoked.
bool did_dump = false;
const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
allocator_dumps = process_memory_dump->allocator_dumps();
for (const auto& pair : allocator_dumps) {
const std::string& dump_name = pair.first;
if (dump_name.find("spdy_session_pool/session") == std::string::npos)
continue;
std::unique_ptr<base::Value> raw_attrs =
pair.second->attributes_for_testing()->ToBaseValue();
base::DictionaryValue* attrs;
ASSERT_TRUE(raw_attrs->GetAsDictionary(&attrs));
base::DictionaryValue* is_active_attrs;
ASSERT_TRUE(attrs->GetDictionary("active", &is_active_attrs));
std::string is_active;
ASSERT_TRUE(is_active_attrs->GetString("value", &is_active));
// No created stream so the session should be idle.
ASSERT_EQ("0", is_active);
did_dump = true;
}
EXPECT_TRUE(did_dump);
spdy_session_pool_->CloseCurrentSessions(ERR_ABORTED);
}

} // namespace net

0 comments on commit 36fa039

Please sign in to comment.