dubbo-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From GitBox <...@apache.org>
Subject [GitHub] ganxinhu commented on issue #1664: memory leak when ExceedPayloadLimitException happens
Date Wed, 25 Apr 2018 03:46:41 GMT
ganxinhu commented on issue #1664: memory leak when ExceedPayloadLimitException happens
URL: https://github.com/apache/incubator-dubbo/issues/1664#issuecomment-384152025
 
 
   It's a FST bug. There is a ThreadLocal variable in class FSTDefaultStreamCoderFactory,
which contains a FSTObjectOutput object for reuse. But when FSTObjectOutput.resetForReUse
invoked, it just will reset the pointer of OutputStream, the space will not be recycled. Therefore,
once a big object has been searialized, the space will not been recycled forever. 
   
   Related code is pasted as below:
   
   ```java
   package com.alibaba.dubbo.common.serialize.support.fst
   public class FstObjectOutput implements ObjectOutput {
   
       private FSTObjectOutput output;
   
       public FstObjectOutput(OutputStream outputStream) {
           output = FstFactory.getDefaultFactory().getObjectOutput(outputStream);
       }
      ...
   }
   
   public class FstFactory {
       private final FSTConfiguration conf = FSTConfiguration.createDefaultConfiguration();
   
       public FSTObjectOutput getObjectOutput(OutputStream outputStream) {
           return conf.getObjectOutput(outputStream);
       }
       ...
   }
   
   public class FSTConfiguration {
       /**
        * utility for thread safety and reuse. Do not close the resulting stream. However
you should close
        * the given OutputStream 'out'
        * @param out - can be null (temp bytearrays stream is created then)
        * @return
        */
       public FSTObjectOutput getObjectOutput(OutputStream out) {
           FSTObjectOutput fstObjectOutput = getOut();
           fstObjectOutput.resetForReUse(out);
           return fstObjectOutput;
       }
   
       protected FSTObjectOutput getOut() {
           FSTObjectOutput fstOut = (FSTObjectOutput) streamCoderFactory.getOutput().get();
           if ( fstOut == null || fstOut.closed ) {
               streamCoderFactory.getOutput().set(new FSTObjectOutput(this));
               return getOut();
           }
           fstOut.conf = this;
           fstOut.getCodec().setConf(this);
           return fstOut;
       }
   }
   protected static class FSTDefaultStreamCoderFactory implements FSTConfiguration.StreamCoderFactory
{
           private FSTConfiguration fstConfiguration;
   
           public FSTDefaultStreamCoderFactory(FSTConfiguration fstConfiguration) {this.fstConfiguration
= fstConfiguration;}
   
           @Override
           public FSTEncoder createStreamEncoder() {
               return new FSTStreamEncoder(fstConfiguration);
           }
   
           @Override
           public FSTDecoder createStreamDecoder() {
               return new FSTStreamDecoder(fstConfiguration);
           }
   
           static ThreadLocal input = new ThreadLocal();
           static ThreadLocal output = new ThreadLocal();
   
           @Override
           public ThreadLocal getInput() {
               return input;
           }
   
           @Override
           public ThreadLocal getOutput() {
               return output;
           }
   
       }
   
   public class FSTObjectOutput implements ObjectOutput {
       /**
        * if out == null => automatically create/reuse a bytebuffer
        *
        * @param out
        */
       public void resetForReUse( OutputStream out ) {
           if ( closed )
               throw new RuntimeException("Can't reuse closed stream");
           getCodec().reset(null);
           if ( out != null ) {
               getCodec().setOutstream(out);
           }
           objects.clearForWrite(conf);
       }
   }
   
   public class FSTStreamEncoder implements FSTEncoder {
       private FSTOutputStream buffout;
       @Override
       public void reset(byte[] out) {
           if (out==null) {
               buffout.reset();
           } else {
               buffout.reset(out);
           }
           clnames.clear();
       }
   }
   
   public final class FSTOutputStream extends OutputStream {
       public void reset() {
           pos = 0;
           off = 0;
       }
   }
   ```
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Mime
View raw message