Skip to content

Reduce GC overhead by call address.toString() in case of timeout only #1401

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

Merged
merged 1 commit into from
Apr 23, 2017
Merged

Conversation

plokhotnyuk
Copy link
Contributor

No description provided.

@slandelle slandelle added this to the 2.0.32 milestone Apr 23, 2017
@slandelle slandelle merged commit d86d481 into AsyncHttpClient:master Apr 23, 2017
@slandelle
Copy link
Contributor

Thanks a bunch!

@slandelle
Copy link
Contributor

BTW, how did you spot it? Just reading the code, or did it show up in some profiling tool?

@plokhotnyuk
Copy link
Contributor Author

plokhotnyuk commented Apr 24, 2017

According to JFR recordings it creates ~40% of allocations in DefaultAsyncHttpClient.executeRequest() calls for our small-sized http requests:

Stack Trace	Average Object Size(bytes)	Total TLAB size(bytes)	Pressure(%)
org.asynchttpclient.DefaultAsyncHttpClient.executeRequest(Request, AsyncHandler)	76.967	19,431,536,992	2.577
  org.asynchttpclient.DefaultAsyncHttpClient.execute(Request, AsyncHandler)	76.967	19,431,536,992	2.577
     org.asynchttpclient.netty.request.NettyRequestSender.sendRequest(Request, AsyncHandler, NettyResponseFuture, boolean)	76.967	19,431,536,992	2.577
        org.asynchttpclient.netty.request.NettyRequestSender.sendRequestWithCertainForceConnect(Request, AsyncHandler, NettyResponseFuture, boolean, ProxyServer, boolean)	76.967	19,431,536,992	2.577
           org.asynchttpclient.netty.request.NettyRequestSender.sendRequestWithOpenChannel(Request, ProxyServer, NettyResponseFuture, AsyncHandler, Channel)	85.822	11,840,735,488	1.571
              org.asynchttpclient.netty.timeout.TimeoutsHolder.initRemoteAddress(InetSocketAddress)	99.687	9,030,445,872	1.198
                 java.net.InetSocketAddress.toString()	99.687	9,030,445,872	1.198
                    java.net.InetSocketAddress$InetSocketAddressHolder.toString()	99.687	9,030,445,872	1.198
                       java.net.InetAddress.toString()	87.325	4,733,398,256	0.628
                          java.lang.StringBuilder.append(String)	135.012	1,988,156,480	0.264
                             java.lang.AbstractStringBuilder.append(String)	135.012	1,988,156,480	0.264
                                java.lang.AbstractStringBuilder.ensureCapacityInternal(int)	135.012	1,988,156,480	0.264
                                   java.util.Arrays.copyOf(char[], int)	135.012	1,988,156,480	0.264
                          java.net.Inet4Address.getHostAddress()	33.506	1,288,388,608	0.171
                             java.net.Inet4Address.numericToTextFormat(byte[])	35.583	1,048,325,408	0.139
                                java.lang.StringBuilder.toString()	32.825	487,483,528	0.065
                                   java.lang.String.<init>(char[], int, int)	38.326	278,029,856	0.037
                                      java.util.Arrays.copyOfRange(char[], int, int)	38.326	278,029,856	0.037
                                java.lang.StringBuilder.<init>()	48	298,944,536	0.04
                                   java.lang.AbstractStringBuilder.<init>(int)	48	298,944,536	0.04
                             java.net.Inet4Address.getAddress()	24	240,063,200	0.032
                          java.lang.StringBuilder.toString()	96	855,612,240	0.113
                             java.lang.String.<init>(char[], int, int)	96	855,612,240	0.113
                                java.util.Arrays.copyOfRange(char[], int, int)	96	855,612,240	0.113
                          java.lang.StringBuilder.<init>()	48	225,779,248	0.03
                             java.lang.AbstractStringBuilder.<init>(int)	48	225,779,248	0.03
                       java.lang.StringBuilder.append(String)	148.515	2,355,534,424	0.312
                          java.lang.AbstractStringBuilder.append(String)	148.515	2,355,534,424	0.312
                             java.lang.AbstractStringBuilder.ensureCapacityInternal(int)	148.515	2,355,534,424	0.312
                                java.util.Arrays.copyOf(char[], int)	148.515	2,355,534,424	0.312
                       java.lang.StringBuilder.toString()	88.25	1,088,598,688	0.144
                          java.lang.String.<init>(char[], int, int)	106.24	854,941,144	0.113
                             java.util.Arrays.copyOfRange(char[], int, int)	106.24	854,941,144	0.113
                       java.lang.StringBuilder.<init>()	48	592,948,592	0.079
                          java.lang.AbstractStringBuilder.<init>(int)	48	592,948,592	0.079
              org.asynchttpclient.netty.request.NettyRequestSender.scheduleRequestTimeout(NettyResponseFuture)	46.241	1,644,922,080	0.218
              org.asynchttpclient.netty.request.NettyRequestSender.writeRequest(NettyResponseFuture, Channel)	32.585	1,165,367,536	0.155
           org.asynchttpclient.netty.request.NettyRequestSender.newNettyRequestAndResponseFuture(Request, AsyncHandler, NettyResponseFuture, ProxyServer, boolean)	64.482	7,298,789,616	0.968
           org.asynchttpclient.netty.request.NettyRequestSender.getOpenChannel(NettyResponseFuture, Request, ProxyServer, AsyncHandler)	32	286,482,928	0.038
           org.asynchttpclient.netty.request.NettyRequestSender.sendRequestWithNewChannel(Request, ProxyServer, NettyResponseFuture, AsyncHandler, boolean)	99.2	5,528,960	0.001

@slandelle
Copy link
Contributor

Mmm, these numbers look off to me. For example, I never see NettyResponseFutures being allocated.
I don't have the cycles for this atm, but I wonder what Honest Profiler would report.

@plokhotnyuk
Copy link
Contributor Author

plokhotnyuk commented Apr 24, 2017

Above I expanded only inet address related part.
Here is fully expanded trace of allocations for DefaultAsyncHttpClient.executeRequest() call:

Stack Trace	Average Object Size(bytes)	Total TLAB size(bytes)	Pressure(%)
   org.asynchttpclient.DefaultAsyncHttpClient.executeRequest(Request, AsyncHandler)	76.967	19,431,536,992	2.577
      org.asynchttpclient.DefaultAsyncHttpClient.execute(Request, AsyncHandler)	76.967	19,431,536,992	2.577
         org.asynchttpclient.netty.request.NettyRequestSender.sendRequest(Request, AsyncHandler, NettyResponseFuture, boolean)	76.967	19,431,536,992	2.577
            org.asynchttpclient.netty.request.NettyRequestSender.sendRequestWithCertainForceConnect(Request, AsyncHandler, NettyResponseFuture, boolean, ProxyServer, boolean)	76.967	19,431,536,992	2.577
               org.asynchttpclient.netty.request.NettyRequestSender.sendRequestWithOpenChannel(Request, ProxyServer, NettyResponseFuture, AsyncHandler, Channel)	85.822	11,840,735,488	1.571
                  org.asynchttpclient.netty.timeout.TimeoutsHolder.initRemoteAddress(InetSocketAddress)	99.687	9,030,445,872	1.198
                     java.net.InetSocketAddress.toString()	99.687	9,030,445,872	1.198
                        java.net.InetSocketAddress$InetSocketAddressHolder.toString()	99.687	9,030,445,872	1.198
                           java.net.InetAddress.toString()	87.325	4,733,398,256	0.628
                              java.lang.StringBuilder.append(String)	135.012	1,988,156,480	0.264
                                 java.lang.AbstractStringBuilder.append(String)	135.012	1,988,156,480	0.264
                                    java.lang.AbstractStringBuilder.ensureCapacityInternal(int)	135.012	1,988,156,480	0.264
                                       java.util.Arrays.copyOf(char[], int)	135.012	1,988,156,480	0.264
                              java.net.Inet4Address.getHostAddress()	33.506	1,288,388,608	0.171
                                 java.net.Inet4Address.numericToTextFormat(byte[])	35.583	1,048,325,408	0.139
                                    java.lang.StringBuilder.toString()	32.825	487,483,528	0.065
                                       java.lang.String.<init>(char[], int, int)	38.326	278,029,856	0.037
                                          java.util.Arrays.copyOfRange(char[], int, int)	38.326	278,029,856	0.037
                                    java.lang.StringBuilder.<init>()	48	298,944,536	0.04
                                       java.lang.AbstractStringBuilder.<init>(int)	48	298,944,536	0.04
                                 java.net.Inet4Address.getAddress()	24	240,063,200	0.032
                              java.lang.StringBuilder.toString()	96	855,612,240	0.113
                                 java.lang.String.<init>(char[], int, int)	96	855,612,240	0.113
                                    java.util.Arrays.copyOfRange(char[], int, int)	96	855,612,240	0.113
                              java.lang.StringBuilder.<init>()	48	225,779,248	0.03
                                 java.lang.AbstractStringBuilder.<init>(int)	48	225,779,248	0.03
                           java.lang.StringBuilder.append(String)	148.515	2,355,534,424	0.312
                              java.lang.AbstractStringBuilder.append(String)	148.515	2,355,534,424	0.312
                                 java.lang.AbstractStringBuilder.ensureCapacityInternal(int)	148.515	2,355,534,424	0.312
                                    java.util.Arrays.copyOf(char[], int)	148.515	2,355,534,424	0.312
                           java.lang.StringBuilder.toString()	88.25	1,088,598,688	0.144
                              java.lang.String.<init>(char[], int, int)	106.24	854,941,144	0.113
                                 java.util.Arrays.copyOfRange(char[], int, int)	106.24	854,941,144	0.113
                           java.lang.StringBuilder.<init>()	48	592,948,592	0.079
                              java.lang.AbstractStringBuilder.<init>(int)	48	592,948,592	0.079
                  org.asynchttpclient.netty.request.NettyRequestSender.scheduleRequestTimeout(NettyResponseFuture)	46.241	1,644,922,080	0.218
                     org.asynchttpclient.netty.timeout.TimeoutsHolder.<init>(Timer, NettyResponseFuture, NettyRequestSender, AsyncHttpClientConfig)	41.976	1,158,452,080	0.154
                        org.asynchttpclient.netty.timeout.TimeoutsHolder.newTimeout(TimerTask, long)	56	511,642,912	0.068
                           io.netty.util.HashedWheelTimer.newTimeout(TimerTask, long, TimeUnit)	56	511,642,912	0.068
                        org.asynchttpclient.netty.timeout.RequestTimeoutTimerTask.<init>(NettyResponseFuture, NettyRequestSender, TimeoutsHolder, int)	16	137,424,112	0.018
                           org.asynchttpclient.netty.timeout.TimeoutTimerTask.<init>(NettyResponseFuture, NettyRequestSender, TimeoutsHolder)	16	137,424,112	0.018
                  org.asynchttpclient.netty.request.NettyRequestSender.writeRequest(NettyResponseFuture, Channel)	32.585	1,165,367,536	0.155
                     io.netty.channel.AbstractChannel.writeAndFlush(Object, ChannelPromise)	32	508,796,416	0.067
                        io.netty.channel.DefaultChannelPipeline.writeAndFlush(Object, ChannelPromise)	32	508,796,416	0.067
                           io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(Object, ChannelPromise)	32	508,796,416	0.067
                              io.netty.channel.AbstractChannelHandlerContext.write(Object, boolean, ChannelPromise)	32	508,796,416	0.067
                                 io.netty.channel.AbstractChannelHandlerContext$WriteAndFlushTask.access$1600(AbstractChannelHandlerContext, Object, ChannelPromise)	32	508,796,416	0.067
                                    io.netty.channel.AbstractChannelHandlerContext$WriteAndFlushTask.newInstance(AbstractChannelHandlerContext, Object, ChannelPromise)	32	508,796,416	0.067
                                       io.netty.util.Recycler.get()	32	508,796,416	0.067
                                          io.netty.channel.AbstractChannelHandlerContext$WriteAndFlushTask$1.newObject(Recycler$Handle)	32	286,072,048	0.038
                                             io.netty.channel.AbstractChannelHandlerContext$WriteAndFlushTask$1.newObject(Recycler$Handle)	32	286,072,048	0.038
                                          io.netty.util.Recycler$Stack.newHandle()	32	222,724,368	0.03
                     io.netty.channel.AbstractChannel.newPromise()	40	372,463,960	0.049
                        io.netty.channel.DefaultChannelPipeline.newPromise()	40	372,463,960	0.049
                     io.netty.channel.DefaultChannelPromise.addListener(GenericFutureListener)	16	8,390,624	0.001
                        io.netty.channel.DefaultChannelPromise.addListener(GenericFutureListener)	16	8,390,624	0.001
                           io.netty.util.concurrent.DefaultPromise.addListener(GenericFutureListener)	16	8,390,624	0.001
                              io.netty.util.concurrent.DefaultPromise.notifyListeners()	16	8,390,624	0.001
               org.asynchttpclient.netty.request.NettyRequestSender.newNettyRequestAndResponseFuture(Request, AsyncHandler, NettyResponseFuture, ProxyServer, boolean)	64.482	7,298,789,616	0.968
                  org.asynchttpclient.netty.request.NettyRequestFactory.newNettyRequest(Request, boolean, ProxyServer, Realm, Realm)	53.586	6,017,332,712	0.798
                     io.netty.handler.codec.http.DefaultFullHttpRequest.<init>(HttpVersion, HttpMethod, String, ByteBuf)	55.598	2,955,123,784	0.392
                        io.netty.handler.codec.http.DefaultFullHttpRequest.<init>(HttpVersion, HttpMethod, String, ByteBuf, boolean)	55.598	2,955,123,784	0.392
                           io.netty.handler.codec.http.DefaultHttpRequest.<init>(HttpVersion, HttpMethod, String, boolean)	54.971	1,477,932,808	0.196
                              io.netty.handler.codec.http.DefaultHttpMessage.<init>(HttpVersion, boolean, boolean)	54.971	1,477,932,808	0.196
                                 io.netty.handler.codec.http.DefaultHttpHeaders.<init>(boolean)	59.521	1,314,856,328	0.174
                                    io.netty.handler.codec.http.DefaultHttpHeaders.<init>(boolean, DefaultHeaders$NameValidator)	59.521	1,314,856,328	0.174
                                       io.netty.handler.codec.DefaultHeadersImpl.<init>(HashingStrategy, ValueConverter, DefaultHeaders$NameValidator)	66.115	986,613,256	0.131
                                          io.netty.handler.codec.DefaultHeaders.<init>(HashingStrategy, ValueConverter, DefaultHeaders$NameValidator)	66.115	986,613,256	0.131
                                             io.netty.handler.codec.DefaultHeaders.<init>(HashingStrategy, ValueConverter, DefaultHeaders$NameValidator, int)	66.115	986,613,256	0.131
                           io.netty.handler.codec.http.DefaultHttpHeaders.<init>(boolean)	59.961	1,361,263,056	0.181
                              io.netty.handler.codec.http.DefaultHttpHeaders.<init>(boolean, DefaultHeaders$NameValidator)	59.961	1,361,263,056	0.181
                                 io.netty.handler.codec.DefaultHeadersImpl.<init>(HashingStrategy, ValueConverter, DefaultHeaders$NameValidator)	68.181	930,402,032	0.123
                                    io.netty.handler.codec.DefaultHeaders.<init>(HashingStrategy, ValueConverter, DefaultHeaders$NameValidator)	68.181	930,402,032	0.123
                                       io.netty.handler.codec.DefaultHeaders.<init>(HashingStrategy, ValueConverter, DefaultHeaders$NameValidator, int)	68.181	930,402,032	0.123
                     io.netty.handler.codec.http.DefaultHttpHeaders.set(HttpHeaders)	40	1,355,441,712	0.18
                        io.netty.handler.codec.DefaultHeaders.set(Headers)	40	1,355,441,712	0.18
                           io.netty.handler.codec.DefaultHeaders.addImpl(Headers)	40	1,355,441,712	0.18
                              io.netty.handler.codec.DefaultHeaders.add0(int, int, Object, Object)	40	1,355,441,712	0.18
                                 io.netty.handler.codec.DefaultHeaders.newHeaderEntry(int, Object, Object, DefaultHeaders$HeaderEntry)	40	1,355,441,712	0.18
                     org.asynchttpclient.netty.request.NettyRequestFactory.requestUri(Uri, ProxyServer, boolean)	73.746	1,088,782,800	0.144
                        java.lang.StringBuilder.<init>()	48	3,021,912	0
                           java.lang.AbstractStringBuilder.<init>(int)	48	3,021,912	0
                        java.lang.StringBuilder.append(String)	88	926,776	0
                           java.lang.AbstractStringBuilder.append(String)	88	926,776	0
                              java.lang.AbstractStringBuilder.ensureCapacityInternal(int)	88	926,776	0
                                 java.util.Arrays.copyOf(char[], int)	88	926,776	0
                        java.lang.StringBuilder.toString()	88	492,824	0
                           java.lang.String.<init>(char[], int, int)	88	492,824	0
                              java.util.Arrays.copyOfRange(char[], int, int)	88	492,824	0
                  org.asynchttpclient.netty.request.NettyRequestSender.newNettyResponseFuture(Request, AsyncHandler, NettyRequest, ProxyServer)	113.202	1,281,456,904	0.17
                     org.asynchttpclient.netty.NettyResponseFuture.<init>(Request, AsyncHandler, NettyRequest, int, ChannelPoolPartitioning, ProxyServer)	24	174,611,184	0.023
               org.asynchttpclient.netty.request.NettyRequestSender.getOpenChannel(NettyResponseFuture, Request, ProxyServer, AsyncHandler)	32	286,482,928	0.038
                  org.asynchttpclient.netty.request.NettyRequestSender.pollPooledChannel(Request, ProxyServer, AsyncHandler)	32	286,482,928	0.038
               org.asynchttpclient.netty.request.NettyRequestSender.sendRequestWithNewChannel(Request, ProxyServer, NettyResponseFuture, AsyncHandler, boolean)	99.2	5,528,960	0.001
                  org.asynchttpclient.resolver.RequestHostnameResolver.resolve(Request, ProxyServer, AsyncHandler)	110	5,526,912	0.001
                     io.netty.resolver.SimpleNameResolver.resolveAll(String)	110	5,526,912	0.001
                        io.netty.resolver.SimpleNameResolver.resolveAll(String, Promise)	110	5,526,912	0.001
                           io.netty.resolver.dns.DnsNameResolver.doResolveAll(String, Promise)	110	5,526,912	0.001
                              io.netty.resolver.dns.DnsNameResolver.doResolveAll(String, DnsRecord[], Promise, DnsCache)	110	5,526,912	0.001
                                 io.netty.resolver.dns.DnsNameResolver.doResolveAllUncached(String, DnsRecord[], Promise, DnsCache)	130.667	4,194,304	0.001
                                    io.netty.resolver.dns.DnsNameResolverContext.resolve(Promise)	56	2,097,144	0
                                       io.netty.resolver.dns.DnsNameResolverContext.internalResolve(Promise)	56	2,097,144	0
                                          io.netty.resolver.dns.DnsNameResolverContext.query(String, DnsRecordType, DnsServerAddressStream, Promise)	56	2,097,144	0
                                             io.netty.handler.codec.dns.DefaultDnsQuestion.<init>(String, DnsRecordType)	56	2,097,144	0
                                                io.netty.handler.codec.dns.AbstractDnsRecord.<init>(String, DnsRecordType, long)	56	2,097,144	0
                                                   io.netty.handler.codec.dns.AbstractDnsRecord.<init>(String, DnsRecordType, int, long)	56	2,097,144	0
                                                      java.net.IDN.toASCII(String)	56	2,097,144	0
                                                         java.net.IDN.toASCII(String, int)	56	2,097,144	0
                                                            java.net.IDN.toASCIIInternal(String, int)	56	2,097,144	0
                                                               java.lang.StringBuffer.<init>(String)	56	2,097,144	0
                                                                  java.lang.AbstractStringBuilder.<init>(int)	56	2,097,144	0
                                    io.netty.resolver.dns.DnsNameResolver$ListResolverContext.<init>(DnsNameResolver, String, DnsRecord[], DnsCache, DnsServerAddressStream)	272	2,048	0
                                       io.netty.resolver.dns.DnsNameResolverContext.<init>(DnsNameResolver, String, DnsRecord[], DnsCache, DnsServerAddressStream)	272	2,048	0
                                          java.util.IdentityHashMap.<init>()	272	2,048	0
                                             java.util.IdentityHashMap.init(int)	272	2,048	0
                                 io.netty.resolver.dns.DnsNameResolver.hostname(String)	48	1,332,608	0
                                    java.net.IDN.toASCII(String)	48	1,332,608	0
                                       java.net.IDN.toASCII(String, int)	48	1,332,608	0
                                          java.lang.StringBuffer.<init>()	48	1,332,608	0
                                             java.lang.AbstractStringBuilder.<init>(int)	48	1,332,608	0
                  org.asynchttpclient.netty.request.NettyRequestSender.scheduleRequestTimeout(NettyResponseFuture)	56	2,048	0

@slandelle
Copy link
Contributor

@plokhotnyuk Please check follow up in 2ea7c06

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

Successfully merging this pull request may close these issues.

2 participants