-
Notifications
You must be signed in to change notification settings - Fork 734
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
about Memory growth test of Tritonserver #1141
Comments
There's a couple of things that could be happening, but the first thing you should check is for dangling Pointer objects. Try to run a command like this:
If you see any output from that, you should find where those Pointer objects are not getting deallocated and call close() on them, or you could use |
looks like there's quite a few there. Since there's lots of "new BytePointer" in Simple.java, which ones need me to do a close() on it? |
Just try to use PointerScope...
|
it will help to release/close by self? |
Kind of, it's like a scope in C++, see the example here: http://bytedeco.org/news/2018/07/17/bytedeco-as-distribution/ |
I did some test today with "PointerScope" as attached. But memory usage is still dangled, vibrated: |
Please check the debug log like I asked you to do above #1141 (comment) |
looks you mean even if "PointerScope" added, there still will be more leaks of pointers, if "PointerScope" does not include all the pointers? |
I added "try (PointerScope scope = new PointerScope()) {" just at the beginning of the Main function, why there's still lots of "Debug: Collecting org.bytedeco.javacpp.Pointer$NativeDeallocator[ownerAddress=0x0,deallocatorAddress=0x0]" in the output log file? |
Those are fine, their ownerAddress is 0. If you see any that have an address other than 0, then you should find what those are. If all that you see do not have an address, then you're probably dealing with GC issues of the Java heap. Try a different one: |
BTW, how did you make sure this is happening only with Java, and not with C++? Maybe it's a problem with Triton... |
good point. |
searched the log file: |
Samuel:
We assume, every two seconds, there will be some member of function "RunInference" be processed, some memory will be allocated, some memory will be freed during each call of "RunInference", so the variation of "memory_allocation_delta_percent" should not be larger than 10%, how do you think? This is the right way to test memory growth of Java process? |
Well, that's a question about Triton more than anything else, I think. All buffers should be preallocated as much as possible, so variations like that don't occur. |
since, each time when to do the reference, in function of "RunInference", we will allocator lots of buffers, do you mean this needs to be replaced by some static/preallocated memory? If we re-allocate these buffers each time when doing inference, this variation is common to Java process? |
That has nothing to do with Java! You're allocating these buffers for Triton, not Java. This is something that needs to be fixed for Triton. |
Yes, we allocate these buffers for Triton to do inference or compare some result. So, let's say, if I allocate these buffers as some static/preallocated ones, then the variation issue is fixed, does that mean the GC is not working well enough? |
Preallocating and reusing objects that use memory on the Java heap helps the GC, but it's possible to tune the GC to be able to cope better with larger amounts of garbage too, yes. |
so you mean the ways listed https://developers.redhat.com/articles/2021/11/02/how-choose-best-java-garbage-collector#parallel_collector here to tune the GC for larger amounts of garbage? |
That kind thing, yes, but if the requests that you get don't require allocating different kinds of buffers all the time, it's more efficient to just reuse those buffers. That's probably what your users are asking about. |
here's the default JVM parameters: root@4a42d065cf6e:/workspace/javacpp_presets_upstream/javacpp-presets/tritonserver# java -XX:+PrintCommandLineFlags -version Which parameters you think that probably need to tune? |
so, for this, since I want to make the largest allocated memory as static ones, how can I know which buffers/object is the largest one? |
Not just the largest one, all of them, if possible. I'm guessing that ideally your users want this to be "garbage free" to get the lowest latency possible, for real time applications, but I'm just guessing. You should try to find out what the needs of your users are, and then we can figure out how to meet those needs. |
temporary, this test is just internally, probably users will have such sort of requirements? I'm not sure what JAVA users will most care about |
Well, if what you care most about is money, HFT is where it's at for low-latency Java applications: But personally I prefer working on embedded systems such as the ones from aicas: |
Samuel: Today I did more tests on GC and Heap:
Why "OU" grows fast here? @saudet |
That's the "old space" apparently: https://docs.oracle.com/javase/7/docs/technotes/tools/share/jstat.html |
I will try this now! Today I did something like: if (!allocated_ptr.isNull()) { JMC says "no memory leak", but still can only run 5600000 iterations, then "unknown exception"... |
There's no 1.5.8-snapshots including the latest JavaCPP? how to make pom.xml to include the latest one? org.bytedeco javacpp-presets 1.5.8-SNAPSHOTorg.bytedeco the above doesn't work, not including the latest code of javapp. |
You can add an entry like this to override the version from the dependencies: <dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.5.8-SNAPSHOT</version>
</dependency> |
thanks, do it now.
still not works: [ERROR] COMPILATION ERROR : even when I delete this: |
I modified javacpp-presets/tritonserver/pom.xml as you wrote above. not works. |
Maybe something went wrong with the latest builds. I've restarted the builds, please try again with |
OK, will do just after breakfast. I need to try my best. |
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project simple: Compilation failure: Compilation failure: not works. I have to try a new clean container. |
Ok, I finally spent a little of time to debug this myself. I think I found the cause of the leak. I've pushed a fix in commit bytedeco/javacpp@0efc632. If you're still not able to get the latest binaries from the snapshots for some reason, you can simply clone https://github.com/bytedeco/javacpp and You'll also need to rebuild the presets for Triton itself after that to make this effective: |
great thanks! try it this morning. |
my god! I did all the things above, but always failed to find the symbols!! [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project simple: Compilation failure: Compilation failure: this make me mad... |
there's no "nm" in java? how can I know if there's "newGlobalRef" in /root/.m2/repository/org/bytedeco/javacpp/1.5.8-SNAPSHOT/javacpp-1.5.8-SNAPSHOT.jar?? |
If you're using the "shaded" library of the presets for Triton, you'll need to update that one as well. JAR files are just zip files, use unzip to extract the classes, and you can use the decompiler javap on those classes. |
looks like there's newGlobalRef in Loader.class: root@55d883c095bc:~/.m2/repository/org/bytedeco/javacpp/1.5.8-SNAPSHOT/tmp/org/bytedeco/javacpp# javap Loader.class |grep newGlobalRef what's shaded? I just use these to compile and install tritonserver: $ mvn clean install --projects .,tritonserver |
in Simple.java, it includes: import org.bytedeco.javacpp.*; what's error there? driving me mad... |
For example, this file: https://oss.sonatype.org/content/repositories/snapshots/org/bytedeco/tritonserver-platform/2.18-1.5.8-SNAPSHOT/tritonserver-platform-2.18-1.5.8-20220318.033114-6-shaded.jar |
I found this in javacpp-presets/tritonserver/samples/pom.xml: org.bytedeco tritonserver-platform 2.18-1.5.8-SNAPSHOT shadedI just remove "shaded" line: org.bytedeco tritonserver-platform 2.18-1.5.8-SNAPSHOTthen do clean install, but, still get the same error...why?? |
[INFO] Changes detected - recompiling the module! it still uses javacpp1.5.7?? why not 1.5.8? |
It's possible, yes, unless we force it to a particular version, as above #1141 (comment). |
Anyway, I've updated the shaded JAR file, so we can use it without Maven, for example, this way: wget https://oss.sonatype.org/content/repositories/snapshots/org/bytedeco/tritonserver-platform/2.18-1.5.8-SNAPSHOT/tritonserver-platform-2.18-1.5.8-20220408.064151-7-shaded.jar
java -cp tritonserver-platform-2.18-1.5.8-20220408.064151-7-shaded.jar SimpleCPUOnly.java -r /workspace/models ... |
compiling is ok now. I am now testing with: java -Xms128m -Xmx384m -Dorg.bytedeco.javacpp.maxPhysicalBytes=800m -Dorg.bytedeco.javacpp.nopointergc=true -jar simple-1.5.8-SNAPSHOT.jar -r "/workspace/server-2.18.0/docs/examples/model_repository/models" -i 10000000 |
10 millions passed! bravo! |
Yes, I'm able to figure out from "oldSampleObject" that "BytePointer(tensor_name)" is not collected from heap. But since I'm not expert of JavaCPP, I'm not able to fix it... |
Don't worry about that one, just apply the patch from above #1141 (comment). |
The fix has now been released with JavaCPP 1.5.8! Thanks for reporting and for testing |
We try to test the memory growth by gather the stats of memory usage when doing inference.
each time when we do an inference, we will get the statistics of memory it allocated. we found that:
("The max allocation of Memory when doing a single inference" - "The average allocation of Memory when doing a single inference") / ("The max allocation of Memory when doing a single inference") = 0.46, which means the variation is too big, why? it varies from about 700MB to 1500MB.
attached is the simple.java file and the test.sh script, probably to reproduce this, one need to modify the dir in the test.sh accordingly.
@saudet
L0_memory_growth.zip
The text was updated successfully, but these errors were encountered: