Skip to content
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

Add Binary Allocator #14201

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

Add Binary Allocator #14201

wants to merge 10 commits into from

Conversation

MrQuansy
Copy link
Contributor

@MrQuansy MrQuansy commented Nov 26, 2024

Description

Add Binary Allocator for object pooling and reuse of large Binary objects to reduce GC overhead.

Features

  • Object pooling for large Binary objects to minimize GC pressure
  • Efficient reuse system for Binary objects
  • Reduced memory allocation overhead

Details

  • Implements variable-length allocation based on Slab allocation strategy
  • Features automatic eviction mechanism to prevent memory bloat
  • Supports automatic start/stop capability for flexible resource management

Next Steps

Integrate Binary Allocator into IoTDB's writing execution.

@MrQuansy MrQuansy marked this pull request as draft November 26, 2024 05:06
@MrQuansy MrQuansy marked this pull request as ready for review November 27, 2024 13:19
Copy link
Contributor

@OneSizeFitsQuorum OneSizeFitsQuorum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work! This is a big step forward in our performance.

But please pay attention to the code style, it seems that the overall code is written very casually and loosely at present...

private int sampleCount;
private final int weight;
private boolean isOld; // Enable to have enough historical data
private final int OLD_THRESHOLD = 100;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final static


import static java.lang.Math.max;

public class AdaptiveWeightedAverage {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add javadoc

sampleCount = 0;
}

public void sample(int newSample) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not seem to be writing friendly, and it feels like adaptiveWeightedAverage is a write more read less structure, should not be implemented this way.

In addition whether we use some mature EMA class such as "com.codahale.metrics.EWMA, don't have to write yourself?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The EWMA implementation in com.codahale.metrics introduces extra work to improve concurrent performance, which wastes additional memory and reduces update performance. We don't need to consider concurrency issues here.

BTW, the AdaptiveWeightedAverage is modified from JDK17 source codes. However, I made some modifications after discovering that memory allocation and deallocation occurs in cycles, such as before and after a request completes. Therefore, the active memory volume fluctuates significantly, so we calculate a moving average based on the peak active memory within each evictor cycle.

/** The default value for {@code evictorShutdownTimeout} configuration attribute. */
private long evictorShutdownTimeoutMillis = 10L * 1000L;

/** The default value for {@code evictorShutdownTimeout} configuration attribute. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe the meaning of these parameters in the Javadoc. The way it is written now is worse than not writing it at all...

private int[] sizeIdx2sizeTab;
final int lookupMaxSize;

final int LOG2_QUANTUM;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not private?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not capitalize variables that are not final static...


public PooledBinary allocateBinary(int reqCapacity) {
if (reqCapacity < allocatorConfig.minAllocateSize
| reqCapacity > allocatorConfig.maxAllocateSize) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

|| ?

state.set(BinaryAllocatorState.OPEN);
evictor =
new GCEvictor(
"binary-allocator-gc-evictor", allocatorConfig.getDurationEvictorShutdownTimeout());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do no use magic string

}

public void close(boolean needReopen) {
if (needReopen) state.set(BinaryAllocatorState.TMP_CLOSE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use {}


package org.apache.iotdb.commons.utils.binaryallocator;

public enum BinaryAllocatorState {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image Describe the transition relationship between these states, and what conditions trigger the transition

AllocatorConfig config = new AllocatorConfig();
config.arenaNum = 1;
BinaryAllocator binaryAllocator = new BinaryAllocator(config);
PooledBinary binary = binaryAllocator.allocateBinary(256);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use Odd number like 255 is better to test jvm allocation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants