-
Notifications
You must be signed in to change notification settings - Fork 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
Implement fast dump #2047 #2121
Conversation
All you need to do is to add the dependency of ‘fast-dump’, 'DumpWrapper' will automatically do the rest. Support Android 5~11. Signed-off-by: xueqiushi <xueqiushi@kuaishou.com>
Nit: can you rename the top folder and artifact name from |
try { | ||
System.loadLibrary("fast-dump") | ||
} catch (e: UnsatisfiedLinkError ) { | ||
e.printStackTrace() |
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.
Ideally there should probably an explicit load method, maybe with a boolean indicating whether loading was successfull. Then the consumer can check that before calling forkDumpHprof
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.
That would make the reflection calls a bit more cumbersome, but also allows to fallback to default if it didn't work.
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.
The check & fallback implements in DumpWrapper.dumpHprofData
with InvocationTargetException
leakcanary-android-utils/src/main/java/leakcanary/DumpWrapper.kt
Outdated
Show resolved
Hide resolved
@Throws(IOException::class) | ||
fun dumpHprofData(fileName: String) { | ||
if (isSupportFastDump()) { | ||
checkNotMainThread() |
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.
Why is not main thread important?
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.
forkDumpHprof
is a synchronous call,it use waitpid
to wait child process to complete dump hprof, and then shark
can analyze it. If someone call it in main thread, it will block the user.
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.
ok. The trick is, this is currently exposed as an API on the LeakCanary object so someone might call it from the main thread. I'm not sure what to do, if we should enforce that at the callsite, switch off to a background thread, or just not use fast dump if called from the main thread.
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.
I think fallback in main thread called situation is better. If someone does not realize that fast dump should be called in a background thread, it is hardly for him to use fast dump correctly.
Switch off to a background thread automatically would make someone confused.
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.
Interesting. So what you're saying is that with "fast dump" the dumping isn't faster, but it's non blocking which means the parent process can keep running while the dump is happening in a child process, so it doesn't make sense to wait for that on the main thread and block. And in that case we might as well use the default API. Ok I like it.
try { | ||
fastDumpClass?.getDeclaredMethod("forkDumpHprof", String::class.java)?.invoke(null, fileName) | ||
} catch (e: Exception) { | ||
e.printStackTrace() |
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.
What exception do you expect here? We should be specific, and handler better than with default logging. Can you use SharkLog
?
Also the fallback on failure should be just Debug.dumpHprofData
no?
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.
Load library fail or something unexpected,add a fallback is a good idea.
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.
Change to forkDumpHprofMethod
|
||
private val fastDumpClass by lazy { | ||
try { | ||
return@lazy Class.forName("com.squareup.leakcanary.FastDump") |
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.
Yep, this is good, it means fast dump is optional and you have to specifically include the artifact to get it.
Rename the top folder and artifact name from 'fast-dump' to 'android-fast-dump' Signed-off-by: xueqiushi <xueqiushi@kuaishou.com>
Signed-off-by: xueqiushi <xueqiushi@kuaishou.com>
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.
Thanks for your contribution @alhah! I'm excited to see native code being contributed to Leak Canary, but since this is the first PR to do so there might be a little more work to get this merged.
In general, your changes look good but I would like to see your CMake list files updated with some additional warning/error checks. Also, would it be possible to update your code to reflect the conventions documented in Google's C++ style guide (See https://google.github.io/styleguide/cppguide.html)?
Thanks again for the hard work!
Signed-off-by: xueqiushi <xueqiushi@kuaishou.com>
Signed-off-by: xueqiushi <xueqiushi@kuaishou.com>
Signed-off-by: xueqiushi <xueqiushi@kuaishou.com>
Is there any other problem? @sstallion |
I do want to merge this but I'm on paternity leave so not working at the moment. |
Congratulations, have a good holiday. |
d360513
to
e6e02bb
Compare
I started looking more closely, playing with it and adding a few minor changes. One thing I'm curious about: when I tried to push to an x86 emulator, of course we don't have a native fast dump lib for it. How can we configure the library so that it's a no-op on non supported architectures, without adb outputting an error:
|
1. Support x86/x86_64 for emulator. 2. Optimize symbol search performance & reliability, support symbol in .gnu_debugdata. 3. Android R fast dump uses another implementation, which is consistent with the lower version. 4. Use c++17 instead of c++11 for make_unique. 5. Workaround for NDK bug: android/ndk#721 Signed-off-by: xueqiushi <xueqiushi@kuaishou.com>
2bc9459
to
f2c9fe3
Compare
|
For example, |
Thanks! This PR has a ton of code, and I'm not familiar with the intricacies of C. However, I do want to enable LeakCanary to benefit from these speedups. As a first step, I'm creating an API to customize the heap dumper in #2237 That way you'll be able to do something like: LeakCanary.config = LeakCanary.config.copy(
heapDumper = HeapDumper {
DumpWrapper.dumpHprofData(it.absolutePath)
}
} |
@alhah hi! With LeakCanary 2.8, it's now possible to customize the heap dumper. I'm really sorry this PR has been open for so long. It's really hard for me to review it as I'm not comfortable with native code. It would be even harder for me to maintain it in the future, so merging this PR also means increased maintenance burden and higher risk. I was thinking, an alternate path here would be for you to create your own repo (e.g. |
That's OK, it's not hard for me, I can integrate KOOM into the custom dumper. |
@alhah Thanks! Do you want to document somewhere (maybe on a Readme in KOOM) how to integrate the two things together? Then I can add a link from the LeakCanary docs to the Koom readme that explains how to use KOOM's heap dump for LeakCanary? |
We are preparing a new version of KOOM, providing an API to support custom dumper. |
We just released 2.1.0 to support custom fork dumper, I tried to integrate it into leakcanary, it works, but the code is not very elegant, I will optimize it and release a new version soon. Here is the patch for test. Here is the logcat, 6757 is the main process id and 6800 is the child process id.
|
Very cool! When you have the new release, can you open an issue with the setup steps and I'll add it to the documentation? |
Sure. |
All you need to do is to add the dependency of ‘fast-dump’, 'DumpWrapper' will automatically do the rest.
Support Android 5~11.
Signed-off-by: xueqiushi xueqiushi@kuaishou.com