Sorry if this is a bit obvious. I did not dive into your code. But I did 
notice that replacePositionalPlaceholders returns buf.String(). If you are 
certain that this is where the memory 'leak' is originating, then the most 
likely scenario is that the returned string is never being collected. Is it 
possible that somehow there is a reference being kept to the string, or an 
object containing the string?

On Sunday, August 30, 2020 at 11:25:15 AM UTC-4, Sarath Prabath Redlapalli 
Jaya wrote:
>
> Hi, we've been observing high memory usage in the following code
> https://github.com/Masterminds/squirrel/blob/master/placeholder.go#L113
>
> We measured from pprof of heap
>
> (pprof) top20
>
> Showing nodes accounting for 360.07MB, 91.31% of 394.32MB total
>
> Dropped 142 nodes (cum <= 1.97MB)
>
> Showing top 20 nodes out of 139
>
>       flat  flat%   sum%        cum   cum%
>
>   101.21MB 25.67% 25.67%   101.21MB 25.67%  bytes.(*Buffer).String
>
>    48.01MB 12.18% 37.84%    48.01MB 12.18%  
> github.com/newrelic/go-agent/v3/newrelic.(*spanAttributeMap).add
>
>    42.61MB 10.81% 48.65%    43.11MB 10.93%  
> github.com/newrelic/go-agent/v3/newrelic.(*txnTrace).witnessNode
>
>    38.54MB  9.77% 58.42%    38.54MB  9.77%  
> go.uber.org/zap/buffer.NewPool.func1
>
>       19MB  4.82% 63.24%       19MB  4.82%  
> github.com/newrelic/go-agent/v3/newrelic.segmentEnd.spanEvent
>
>    16.51MB  4.19% 67.43%    91.04MB 23.09%  
> github.com/newrelic/go-agent/v3/newrelic.endDatastoreSegment
>
>    14.01MB  3.55% 70.98%    18.01MB  4.57%  
> github.com/newrelic/go-agent/v3/newrelic.newTxn
>
>    13.51MB  3.43% 74.41%    93.13MB 23.62%  
> github.com/newrelic/go-agent/v3/newrelic.endExternalSegment
>
>    12.01MB  3.05% 77.45%    12.01MB  3.05%  
> github.com/newrelic/go-agent/v3/newrelic.getStackTrace
>
>    10.51MB  2.66% 80.12%    10.51MB  2.66%  
> github.com/newrelic/go-agent/v3/newrelic.(*slowQueries).insertAtIndex
>
>        8MB  2.03% 82.15%        8MB  2.03%  
> github.com/newrelic/go-agent/v3/newrelic.newSlowQueries
>
>     6.51MB  1.65% 85.73%     6.51MB  1.65%  
> github.com/DataDog/datadog-go/statsd.newStatsdBuffer
>
>        4MB  1.01% 86.75%    52.01MB 13.19%  
> github.com/newrelic/go-agent/v3/newrelic.(*spanAttributeMap).addString
>
>     3.50MB  0.89% 87.64%     3.50MB  0.89%  
> go.uber.org/zap.(*Logger).clone
>
>     3.50MB  0.89% 88.52%     3.50MB  0.89%  
> github.com/newrelic/go-agent/v3/newrelic.externalMetricKey.scopedMetric
>
>        3MB  0.76% 89.28%        3MB  0.76%  
> github.com/newrelic/go-agent/v3/newrelic.addUserAttribute
>
>        3MB  0.76% 90.05%        3MB  0.76%  strings.(*Builder).WriteString
>
>     2.50MB  0.63% 90.68%     6.06MB  1.54%  encoding/json.Unmarshal
>
>     2.50MB  0.63% 91.31%     2.50MB  0.63%  context.(*cancelCtx).Done
>
> =====
>
> Resetting the buffer by defer didn't help either. So moved to string 
> builder like this
>
> func replacePositionalPlaceholders(sql, prefix string) (string, error) {
> buf := &strings.Builder{}
> defer buf.Reset()
>
> i := 0
> for {
> p := strings.Index(sql, "?")
> if p == -1 {
> break
> }
>
> if len(sql[p:]) > 1 && sql[p:p+2] == "??" { // escape ?? => ?
> buf.WriteString(sql[:p])
> buf.WriteString("?")
> if len(sql[p:]) == 1 {
> break
> }
> sql = sql[p+2:]
> } else {
> i++
> buf.WriteString(sql[:p])
> fmt.Fprintf(buf, "%s%d", prefix, i)
> sql = sql[p+1:]
> }
> }
>
> buf.WriteString(sql)
> return buf.String(), nil
> }
>
> ======
>
> This didn't help either, from the results below
>
> (pprof) top20
>
> Showing nodes accounting for 220.09MB, 90.37% of 243.55MB total
>
> Dropped 126 nodes (cum <= 1.22MB)
>
> Showing top 20 nodes out of 135
>
>       flat  flat%   sum%        cum   cum%
>
>    33.97MB 13.95% 13.95%    33.97MB 13.95%  strings.(*Builder).Write
>
>    29.07MB 11.94% 25.89%    29.57MB 12.14%  
> github.com/newrelic/go-agent/v3/newrelic.(*txnTrace).witnessNode
>
>    28.01MB 11.50% 37.39%    28.01MB 11.50%  
> github.com/newrelic/go-agent/v3/newrelic.(*spanAttributeMap).add
>
>    24.34MB  9.99% 47.38%    24.34MB  9.99%  strings.(*Builder).WriteString
>
>    18.52MB  7.60% 54.98%    18.52MB  7.60%  
> go.uber.org/zap/buffer.NewPool.func1
>
>    11.01MB  4.52% 59.50%    60.59MB 24.88%  
> github.com/newrelic/go-agent/v3/newrelic.endExternalSegment
>
>    10.01MB  4.11% 63.61%    13.51MB  5.55%  
> github.com/newrelic/go-agent/v3/newrelic.newTxn
>
>       10MB  4.11% 67.72%       10MB  4.11%  
> github.com/newrelic/go-agent/v3/newrelic.segmentEnd.spanEvent
>
>        7MB  2.88% 73.73%        7MB  2.88%  
> github.com/newrelic/go-agent/v3/newrelic.(*slowQueries).insertAtIndex
>
>        7MB  2.88% 76.60%    50.02MB 20.54%  
> github.com/newrelic/go-agent/v3/newrelic.endDatastoreSegment
>
>     6.51MB  2.67% 79.28%     6.51MB  2.67%  
> github.com/DataDog/datadog-go/statsd.newStatsdBuffer
>
>        6MB  2.46% 81.74%     6.50MB  2.67%  
> github.com/newrelic/go-agent/v3/newrelic.addUserAttribute
>
>     5.50MB  2.26% 84.00%     5.50MB  2.26%  
> github.com/newrelic/go-agent/v3/newrelic.getStackTrace
>
>        3MB  1.23% 85.23%        3MB  1.23%  
> github.com/newrelic/go-agent/v3/newrelic.newSlowQueries
>
>        3MB  1.23% 86.47%        3MB  1.23%  
> go.uber.org/zap.(*Logger).clone
>
>        3MB  1.23% 87.70%        3MB  1.23%  
> github.com/newrelic/go-agent/v3/newrelic.externalMetricKey.scopedMetric
>
>     2.50MB  1.03% 88.72%    30.51MB 12.53%  
> github.com/newrelic/go-agent/v3/newrelic.(*spanAttributeMap).addString
>
>        2MB  0.82% 90.37%        2MB  0.82%  encoding/hex.EncodeToString
>
> (pprof) peek Write
>
> Showing nodes accounting for 243.55MB, 100% of 243.55MB total
>
> ----------------------------------------------------------+-------------
>
>       flat  flat%   sum%        cum   cum%   calls calls% + context   
>
> ----------------------------------------------------------+-------------
>
>                                            33.97MB   100% |   fmt.Fprintf
>
>    33.97MB 13.95% 13.95%    33.97MB 13.95%                | 
> strings.(*Builder).Write
>
> ----------------------------------------------------------+-------------
>
>                                            22.34MB 91.78% |   
> github.com/XXXXX/squirrel.replacePositionalPlaceholders
>
>                                                2MB  8.22% |   
> net/url.(*URL).String
>
>    24.34MB  9.99% 23.94%    24.34MB  9.99%                | 
> strings.(*Builder).WriteString
>
> ----------------------------------------------------------+-------------
>
>                                             1.16MB   100% |   
> encoding/json.compact
>
>          0     0% 23.94%     1.16MB  0.48%                | 
> bytes.(*Buffer).Write
>
>                                             1.16MB   100% |   
> bytes.(*Buffer).grow
>
> ----------------------------------------------------------+-------------
>
>                                             6.51MB   100% |   
> github.com/DataDog/datadog-go/statsd.New
>
>          0     0% 23.94%     6.51MB  2.67%                | 
> github.com/DataDog/datadog-go/statsd.newWithWriter
>
>                                             6.51MB   100% |   
> github.com/DataDog/datadog-go/statsd.newBufferPool
>
> ----------------------------------------------------------+-------------
>
>                                            12.01MB   100% |   
> go.uber.org/zap.(*SugaredLogger).log
>
>          0     0% 23.94%    12.01MB  4.93%                | 
> go.uber.org/zap/zapcore.(*CheckedEntry).Write
>
>                                            12.01MB   100% |   
> go.uber.org/zap/zapcore.(*ioCore).Write
>
> ----------------------------------------------------------+-------------
>
>                                            12.01MB   100% |   
> go.uber.org/zap/zapcore.(*CheckedEntry).Write
>
>          0     0% 23.94%    12.01MB  4.93%                | 
> go.uber.org/zap/zapcore.(*ioCore).Write
>
>                                            12.01MB   100% |   
> go.uber.org/zap/zapcore.consoleEncoder.EncodeEntry
>
> ----------------------------------------------------------+-------------
>
>                                                1MB   100% |   
> golang.org/x/net/http2.(*Framer).readMetaFrame
>
>          0     0% 23.94%        1MB  0.41%                | 
> golang.org/x/net/http2/hpack.(*Decoder).Write
>
>                                                1MB   100% |   
> golang.org/x/net/http2/hpack.(*Decoder).parseHeaderFieldRepr
>
> ----------------------------------------------------------+-------------
>
> (pprof) 
>
>
> Please help how to debug this more
>
>
> Regards
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/c5061ff6-abcb-4c47-861b-d764f571eb37o%40googlegroups.com.

Reply via email to