Giter Club home page Giter Club logo

Comments (7)

ewjmulder avatar ewjmulder commented on June 16, 2024

This page: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html#sthref28
Seems to suggest concurrent is the way to go, so G1. But even that can pause up to 1 second, which is way too long. We should do a test in practice with a VM memory monitor and see how GC runs actually perform with parallel or concurrent collectors.

from immerse.

ewjmulder avatar ewjmulder commented on June 16, 2024

Changing GC settings (and also JVM memory settings) does indeed make a big difference in performance. Probably we are generating a lot of 'waste' each step. Setting the GC to G1 makes performance worse unfortunately. Also, trying to manually call System.gc() a little more often results in very bad performance. The default setup (on the Pine64) seems to work quite well in that it does very regular GC's (about every .8 secs) and they will make the step run only a few millis slower which does not result in audible hickups. Still there seems to be a way possible to tweak this to a more desirable setting. If once every .8 seconds could be doubled or tripled, it would seem the running time per gc should be lower and thus the impact on the step should be less. But maybe first try a memory profiler on the running application (jconsole) to see what is happening under the hood. A possible approach could be to reuse all heap objects and arrays in the step. There will never be 2 steps running simultaniously, so declaring everything once and then reusing the arrays and objects should be possible. Esp. in case of arrays which are very mutable by nature and also the wrapper object inner class that is used could easily be reused instead of recreated. The only tricky thing is you never know how big the amount of frames needed of the next step is going to be... Maybe either have a very big possible size in memory or have several 'key' sizes and pick the closest one or create a new one if needed.

from immerse.

ewjmulder avatar ewjmulder commented on June 16, 2024

Memory sampling shows most memory is used by byte[] followed shortly by short[] and much later HashMap$KeyIterator. The last one is probably because of lambdas and streaming and less relevant to fix. The int[] and short[] might be interesting to fix. The problem mentioned in the previous comment:
"The only tricky thing is you never know how big the amount of frames needed of the next step is going to be" is a valid point, but actually not that hard to solve. Because there is a practical maximum for the amountOfFramesNeeded, namely a full buffer to fill. If no frames are left in the buffer, we need:
buffer millis * amount of frames per milli * amount of bytes per frame = max amount of bytes to write
And maybe add 10% or so to incorporate unreliability of current frame positions in the soundcard. If you always have 1 of those per sound card and reuse it ... but then concurrent gathering is risked, maybe have 2 that cycle, since never more than 2 can be used. Same goes for the short[] that are used in between. Memory use will be greatly reduced, only downside is code readability. We could use some kind of StepContext object that keeps (public) pointers to all arrays needed in the process and the current size them. Also all places where they are used that size should be used to limit the reading / writing to the right amount of bytes/shorts.

from immerse.

ewjmulder avatar ewjmulder commented on June 16, 2024

Also from jvisualvm: it's clear that GC and the warning about a slow loop are connected. For the local laptop the gc time even decreases until under the 5 millis limit, propbably because of warmup of the GC code itself. Using System.gc() is no help, since it's very CPU heavy. Probably always the more expensive full gc? So it might be interesting to find a way to more regularly trigger 'shallow gc'.

from immerse.

ewjmulder avatar ewjmulder commented on June 16, 2024

Ultimate GC knowledge resource:
https://plumbr.io/java-garbage-collection-handbook

from immerse.

ewjmulder avatar ewjmulder commented on June 16, 2024

Conclusion: System.gc is always full GC, so not applicable. Minor GC is not possible to trigger by API, and also not handy to do often, otherwise tenuring will be hampered. But it is possible to keep control over minor GC'ing, by reading the mem usage from MX beans and requesting a big enough piece of memory at the time of desired minor GC. There are lots of other options possible to get more control over GC, for instance object pooling and Memory/GC flags in the JVM. Cool, but a bit too intrusive and not worthwile atm. The manual minor GC trigger is implemented in a basic form and might be made smarter at a later time. Also, some other ideas have been documented or put into an issue.

Left to do before closing this story: test the current code on Pine64 and see if it works good (enough) for now. Keep an eye on: GC frequency and step time.

from immerse.

ewjmulder avatar ewjmulder commented on June 16, 2024

Turns out to be a lot more complicated then just setting a flag for another collector. There will always be a 'stop the world' marking phase for any collector. For alpha we have done enough and documented thoughts and ideas for more complicated approaches.

from immerse.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.