Implementation ideas
Object-Cache Variant (Garbage free, low memory usage)
see details at https://inspectit-performance.atlassian.net/wiki/display/VI/Invocation+trace+restructuring
Our thoughts (at least from Matthias):
- object caches
- introduce a level of complexity and another source of contention if multiple threads want to store the same kind of sensor data (e.g. timer data)
- hard to set the required amount e.g. how many timer data will be cached if the ringbuffer contains 10000 elements
- what happens if 7000 is specified and inspectIT only creates timer data => 3000 elements in the buffer could not be used
- dynamic cache behaviour (allocate new object if empty) could bring flexibility on the cost of more complexity to handle the dynamic memory usage
- good to handle peaks
- not so good if required amount is often a bit above the predefined limit
- memory usage
- garbage free with fixed object cache amounts
- mostly garbage free with dynamic cache
- wasted objects are the ones which are hold in the cache each time an entry is written to the ringbuffer
- well sized caches reduce memory overhead
Combined Object Variant (Garbage free, high memory usage)
This variant is inspired by the sample project https://github.com/mikeb01/ticketing which has been developed by Michael Barker (Maintaner LMAX Disruptor) for his talk at Devoxx'11. It uses Javolution's Struct and Union for memory layout optimization.
The idea of this variant is to create an object (like a container) which holds one object of each sensor data. These container objects are used to handle each type of sensor data in the same ringbuffer. A flag (most likely the sensor type id) defines what type of sensor data is actively used (stored) in the container. Producers will set the flag and update only the corresponding sensor data. Later, the consumer checks the flag and retrieves the corresponding sensor data.
no additional complexity and contention compared to object caches
solution is decoupled from sensor data. Producer/Consumer can work only on timer data and short afterwards only on sql data. The ringbuffer doesn't care. In comparison, the object cache variant is coupled to the sensor data
flexibility is paid with a high number of wasted objects. Wasted objects are the ones which are not actively used, basically in each container object n - 1 elements are wasted objects at each time
a new type of sensor data increases the memory consumption much because each container object will increase by that size.
The screenshot contains two variants for the consumer. First, the consumer could directly send a batch of sensor data to the CMR. Second, the consumer of the first ringbuffer marshall just the objects and put them in another ringbuffer. A consumer on that ringbuffer does the actual sending. The second solution would decouple the marshalling and sending with the price of more ressource usage (one ringbuffer + one consumer more)