Skip to content

Shared classloader for agent and jmx-fetch#1199

Merged
randomanderson merged 5 commits into
masterfrom
landerson/shared-classloader
Feb 11, 2020
Merged

Shared classloader for agent and jmx-fetch#1199
randomanderson merged 5 commits into
masterfrom
landerson/shared-classloader

Conversation

@randomanderson
Copy link
Copy Markdown
Contributor

With this pull request, the agent classloader and jmx-fetch classloader share a common parent. Added to the parent classloader are the libraries shared between them (currently only dogstatsd and guava).

The main changes are:

  • Adding the parent in Agent.java
  • Changing the packaging in gradle fo another internal jar

The benefits are:

0.43.0-SNAPSHOT (post jackson removal) This Pull
dd-java-agent.jar file size 20.8 15.2
Old used (memcheck) 16.26 14.27
Old comm (memcheck) 156 152

plus minor decreases across other memory metrics.

Follow on work may include integrating BootstrapProxy into the hierarchy and changing the DatadogClassloaders not to inherit from URLClassloader

@randomanderson randomanderson requested a review from a team as a code owner February 3, 2020 21:33
@randomanderson randomanderson force-pushed the landerson/shared-classloader branch from 2deea42 to 42fb303 Compare February 3, 2020 22:04
Comment thread gradle/dependencies.gradle Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a lot of manual dependency management that is very easy to get wrong. Instead maybe you would consider just somehow including jmxfetch into existing agent jar?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is worth thinking about automating a bit more. However, I suspect it will have to be semi-manual as we upgrade different components.

I think it is mostly going to effect us when we upgrade jmxfetch, since I don't believe dogstatsd has many dependencies.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've merged change #1204 in this method to master. Will be small merge conflict :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is synchronized needed for this method ? And AGENT_CLASSLOADER not volatile at the same time?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. Just following the comments in the class that said access to the classloader fields need to be synchronized. I know at one point startDatadogAgent() and similar methods could have been called by multiple thread because of weird classloading situations.

I think that might have been fixed with #1084 but the synchronized attributes were never removed so I don't know.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in this case, I think synchronized or some other lock is the right choice.
If we had any reads outside, the synchronized block we also need to make the field volatile, but I don't think we do.

Since this is effectively a lazy singleton, the one other approach we could take is a holder class - like...
class AgentClassLoaderHolder {
static final DatadogClassLoader loader = ...
}

The main benefit of that approach is that the locking is handled implicitly through the JVM class init checking and gets optimized away once JIT-ted. However, we're not accessing these fields enough for that to be a significant issue.

And if there's any context that needs to be captured by the Holder class, this approach doesn't really work.

In short - for now, I think this is probably the right solution.

@randomanderson randomanderson force-pushed the landerson/shared-classloader branch from 42fb303 to 9023c6e Compare February 11, 2020 16:45
Copy link
Copy Markdown
Contributor

@tylerbenson tylerbenson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would have preferred common instead of shared, but not a big deal. This works for me. Have you confirmed the resulting dd-java-agent.jar looks how you expect?

@randomanderson randomanderson merged commit c28bf21 into master Feb 11, 2020
@randomanderson randomanderson deleted the landerson/shared-classloader branch February 11, 2020 18:48
@tylerbenson tylerbenson added this to the 0.43.0 milestone Feb 11, 2020
@dougqh
Copy link
Copy Markdown
Contributor

dougqh commented Feb 11, 2020

0.43.0-SNAPSHOT (post jackson removal) This Pull
dd-java-agent.jar file size 20.8
Old used (memcheck) 16.26
Old comm (memcheck) 156

Nice, did we see a drop in metaspace as well -- or was that mostly covered by the jackson change?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tag: performance Performance related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants