29
29
import io .netty .channel .socket .nio .NioServerSocketChannel ;
30
30
import io .netty .channel .socket .nio .NioSocketChannel ;
31
31
import org .elasticsearch .common .Booleans ;
32
+ import org .elasticsearch .common .unit .ByteSizeValue ;
32
33
import org .elasticsearch .monitor .jvm .JvmInfo ;
33
34
34
35
public class NettyAllocator {
35
36
36
37
private static final ByteBufAllocator ALLOCATOR ;
38
+ private static final String DESCRIPTION ;
37
39
38
40
private static final String USE_UNPOOLED = "es.use_unpooled_allocator" ;
39
41
private static final String USE_NETTY_DEFAULT = "es.unsafe.use_netty_default_allocator" ;
42
+ private static final String USE_NETTY_DEFAULT_CHUNK = "es.unsafe.use_netty_default_chunk_and_page_size" ;
40
43
41
44
static {
42
45
if (Booleans .parseBoolean (System .getProperty (USE_NETTY_DEFAULT ), false )) {
43
46
ALLOCATOR = ByteBufAllocator .DEFAULT ;
47
+ DESCRIPTION = "[name=netty_default, factors={es.unsafe.use_netty_default_allocator=true}]" ;
44
48
} else {
49
+ final long heapSizeInBytes = JvmInfo .jvmInfo ().getMem ().getHeapMax ().getBytes ();
50
+ final boolean g1gcEnabled = Boolean .parseBoolean (JvmInfo .jvmInfo ().useG1GC ());
51
+ final long g1gcRegionSizeInBytes = JvmInfo .jvmInfo ().getG1RegionSize ();
52
+ final boolean g1gcRegionSizeIsKnown = g1gcRegionSizeInBytes != -1 ;
53
+ ByteSizeValue heapSize = new ByteSizeValue (heapSizeInBytes );
54
+ ByteSizeValue g1gcRegionSize = new ByteSizeValue (g1gcRegionSizeInBytes );
55
+
45
56
ByteBufAllocator delegate ;
46
- if (useUnpooled ()) {
57
+ if (useUnpooled (heapSizeInBytes , g1gcEnabled , g1gcRegionSizeIsKnown , g1gcRegionSizeInBytes )) {
47
58
delegate = UnpooledByteBufAllocator .DEFAULT ;
59
+ DESCRIPTION = "[name=unpooled, factors={es.unsafe.use_unpooled_allocator=" + userForcedUnpooled ()
60
+ + ", g1gc_enabled=" + g1gcEnabled
61
+ + ", g1gc_region_size=" + g1gcRegionSize
62
+ + ", heap_size=" + heapSize + "}]" ;
48
63
} else {
49
64
int nHeapArena = PooledByteBufAllocator .defaultNumHeapArena ();
50
- int pageSize = PooledByteBufAllocator .defaultPageSize ();
51
- int maxOrder = PooledByteBufAllocator .defaultMaxOrder ();
65
+ int pageSize ;
66
+ int maxOrder ;
67
+ if (useDefaultChunkAndPageSize ()) {
68
+ pageSize = PooledByteBufAllocator .defaultPageSize ();
69
+ maxOrder = PooledByteBufAllocator .defaultMaxOrder ();
70
+ } else {
71
+ pageSize = 8192 ;
72
+ if (g1gcEnabled == false || g1gcRegionSizeIsKnown == false || g1gcRegionSizeInBytes >= (4 * 1024 * 1024 )) {
73
+ // This combined with a 8192 page size = 1 MB chunk sizes
74
+ maxOrder = 7 ;
75
+ } else if (g1gcRegionSizeInBytes >= (2 * 1024 * 1024 )) {
76
+ // This combined with a 8192 page size = 512 KB chunk sizes
77
+ maxOrder = 6 ;
78
+ } else {
79
+ // This combined with a 8192 page size = 256 KB chunk sizes
80
+ maxOrder = 5 ;
81
+ }
82
+ }
52
83
int tinyCacheSize = PooledByteBufAllocator .defaultTinyCacheSize ();
53
84
int smallCacheSize = PooledByteBufAllocator .defaultSmallCacheSize ();
54
85
int normalCacheSize = PooledByteBufAllocator .defaultNormalCacheSize ();
55
86
boolean useCacheForAllThreads = PooledByteBufAllocator .defaultUseCacheForAllThreads ();
56
87
delegate = new PooledByteBufAllocator (false , nHeapArena , 0 , pageSize , maxOrder , tinyCacheSize ,
57
88
smallCacheSize , normalCacheSize , useCacheForAllThreads );
89
+ ByteSizeValue chunkSize = new ByteSizeValue (pageSize << maxOrder );
90
+ DESCRIPTION = "[name=elasticsearch_configured, chunk_size=" + chunkSize
91
+ + ", factors={es.unsafe.use_netty_default_chunk_and_page_size=" + useDefaultChunkAndPageSize ()
92
+ + ", g1gc_enabled=" + g1gcEnabled
93
+ + ", g1gc_region_size=" + g1gcRegionSize + "}]" ;
58
94
}
59
95
ALLOCATOR = new NoDirectBuffers (delegate );
60
96
}
@@ -64,6 +100,10 @@ public static ByteBufAllocator getAllocator() {
64
100
return ALLOCATOR ;
65
101
}
66
102
103
+ public static String getAllocatorDescription () {
104
+ return DESCRIPTION ;
105
+ }
106
+
67
107
public static Class <? extends Channel > getChannelType () {
68
108
if (ALLOCATOR instanceof NoDirectBuffers ) {
69
109
return CopyBytesSocketChannel .class ;
@@ -80,12 +120,34 @@ public static Class<? extends ServerChannel> getServerChannelType() {
80
120
}
81
121
}
82
122
83
- private static boolean useUnpooled () {
123
+ private static boolean useUnpooled (long heapSizeInBytes , boolean g1gcEnabled , boolean g1gcRegionSizeIsKnown , long g1RegionSize ) {
124
+ if (userForcedUnpooled ()) {
125
+ return true ;
126
+ } else if (heapSizeInBytes <= 1 << 30 ) {
127
+ // If the heap is 1GB or less we use unpooled
128
+ return true ;
129
+ } else if (g1gcEnabled == false ) {
130
+ return false ;
131
+ } else {
132
+ // If the G1GC is enabled and the region size is known and is less than 1MB we use unpooled.
133
+ boolean g1gcRegionIsLessThan1MB = g1RegionSize < 1 << 20 ;
134
+ return (g1gcRegionSizeIsKnown && g1gcRegionIsLessThan1MB );
135
+ }
136
+ }
137
+
138
+ private static boolean userForcedUnpooled () {
84
139
if (System .getProperty (USE_UNPOOLED ) != null ) {
85
140
return Booleans .parseBoolean (System .getProperty (USE_UNPOOLED ));
86
141
} else {
87
- long heapSize = JvmInfo .jvmInfo ().getMem ().getHeapMax ().getBytes ();
88
- return heapSize <= 1 << 30 ;
142
+ return false ;
143
+ }
144
+ }
145
+
146
+ private static boolean useDefaultChunkAndPageSize () {
147
+ if (System .getProperty (USE_NETTY_DEFAULT_CHUNK ) != null ) {
148
+ return Booleans .parseBoolean (System .getProperty (USE_NETTY_DEFAULT_CHUNK ));
149
+ } else {
150
+ return false ;
89
151
}
90
152
}
91
153
0 commit comments