Comments (7)
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.
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.
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.
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.
Ultimate GC knowledge resource:
https://plumbr.io/java-garbage-collection-handbook
from immerse.
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.
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)
- AudioInputBuffer should actively keep live streams in sync HOT 1
- Support all audio formats for live streams HOT 3
- Refactor out input/output flag in ImmerseAudioFormat
- Can Url and Supplied Audio Resources still be live? HOT 1
- Research Java Sound API behaviour of different microphones HOT 3
- Research detailed behaviour of SourceDataLine HOT 8
- Refactor UdpAudioResource to better handle the many parameters
- Implement own audio format converters that use minimal amount of buffering
- General volume feature for every playback HOT 1
- Now that we have DynamicData for all ScenarioSettings with time state, can we get rid of the Factory stuff?
- Generify some DynamicData stuff in ActiveScenario?
- Measure delay in DynamicData start time and real audio start time and consider refactor
- Re-research right internal OS buffer size for all systems HOT 1
- Bug: playback randomly stops after heavy stuttering HOT 2
- Is dynamic volume setting linear?
- Does dragon wings file cause ticks in plackback because of overflow in Audacity? HOT 2
- Research and fix weird indexoutofbounds bug
- Is stopping playback a source of hickups?
- Bug: AudioInputBuffer ArrayIndexOutOfBounds
- Performance issue: playing through adventure service is much heavier on CPU than local HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from immerse.