-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Flatten atomic arrays, add tests for LRUMap size #3675
Conversation
Had to change the JOL measurement code so that the full test suite runs. This also changed the numbers a bit, I've adjusted the original PR comment. |
@yawkat could you rebase this? There was a merge to 2.14 that removed some unnecessary methods from PrivateMaxEntriesMap. |
will do |
@pjfanning you mean 6eacc7b? it's already in. |
very minor field removals you can also make,
|
src/test/java/com/fasterxml/jackson/databind/MapperFootprintTest.java
Outdated
Show resolved
Hide resolved
|
||
public class MapperFootprintTest { | ||
@Test | ||
@Ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see comment below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah. Another thing we can do to avoid running as part of test suite (but to allow manual run) would be to move under failing. But we can figure out best way later on.
Sounds great so far! Just LMK when you feel this is ready @yawkat and I'll merge it in. I wonder if we could/should start using |
oh this is annoying – I thought just the .subtract fixed it, but apparently I just forgot to un-ignore the test so CI passed... JOL goes through all objects transitively referenced by a given root (in this case ObjectMapper), and counts them up. For jackson, much of this is reflection instances, e.g. The solution to this is to only count the new objects each new ObjectMapper references. That way, the core reflection instances are not counted. This is why I use the GraphLayout.subtract method in my test: I create two ObjectMappers, and only count the memory footprint of the objects that they don't share. Unfortunately the test suite still fails when using To be clear, the test works well when run in isolation, and the footprint results I listed in the PR text are good. But I'd hoped to get the test running in CI, but it seems to be too flaky for that atm. I have disabled it with |
I use GcFinalization.awaitFullGc() from guava’s testlib for anything that depends on that running (e.g. weak/soft references). I use Parallel GC for those tests as region based, like G1, are more incremental. That might help stabilize here. |
Otherwise for a rougher estimate you can try jamm which won’t be impacted by GC moves as higher level than address checks for its dedupe. |
@ben-manes awaitFullGc is better than the loop, and guava is already in the pom, thanks. However it does not seem to be enough, the fact that even running the analysis twice does not help seems to indicate that gc is triggered even by two calls to new ObjectMapper. I hadn't heard of jamm, but a quick look at the api does not show a way to run the equivalent of the subtract call in jol? It is needed in order to exclude objects that are global, such as reflection instances. (btw re your other optimization suggestions, they seem reasonable, but I will let someone that is actually familiar with the LRUMap impl do them in a future PR) |
The default GC is probably G1, so it will only collect a single region. Also if your test suite is parallelized then other tests might cause some mayhem if you are relying on stable physical addresses. That would require isolated testing this is more finicky than normal cases. I think that |
Yea, I don't know if the tests are parallel, that would be an added complication. I haven't tried it, but the problem I see with If I understand correctly what jamm |
Thanks, that makes more sense to me now. It sounds like this should not be run as part of the normal test suite due to global pollution. What about creating a new test category and running this exclusively and outside of the normal suite? |
Yea, that sounds reasonable. I don't want to fiddle with the build too much in this PR, but we can do it after the fix is in. Another solution could be changing jol to use object identity instead of addresses for the subtract call. I've reached out to shipilev about this. |
Ok yeah, while CI would of course be really good to have, manually run verification is enough for this PR. Follow-up steps then could include:
But even without these I think we'd be ready for minimal set of 2.14.1, and could consider if there are other critical fixes/improvements to add, before proceeding. Thank you @yawkat @ben-manes and @pjfanning for all your work here, I very much appreciate your expertise and help. |
@cowtowncoder correct, the PR is ready to merge, and agree on the follow up steps. I can take a look at the testing situation tomorrow, most likely using @ben-manes' idea of a different test group. Then it can run in CI too. |
It's safe to proceed with this IMHO. The new map is slower than the v2.14.0 map due to more contention on the smaller readBuffer. Nothing drastic. And for ObjectMapper, there is plenty of other places where CPU time is spent so all in all, I doubt if the small slowdown in the PrivateMaxEntriesMap will have any real effect.
|
I'm not sure that the extra changes suggested for PrivateMaxEntriesMap will have much effect. |
Ok. Thank you for getting these numbers @pjfanning ! Somewhat disappointing to note no performance improvement for test cases, although I realize the main goal was to avoid that one-off for cache filling up. But I agree that either way for steady state effect would probably not be measurable for typical usage since cache lookup rate is not super high. We'll go with this. |
See #3665
readBuffers
array to be one-dimensional, this should have no performance impact (if it does, probably positive)Using the JOL test, I compared the footprints of various versions of this code. My machine has 24 cores, which influences some of the results.
The tests before
READ_BUFFERS = 4
depend on cpu count. As you can see, with all the changes in this PR, we are barely above the memory use of 2.13.