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