2017-10-11 10 views
0

Redisson을 통해 Redis를 배우려고합니다. 다음은 여러 스레드를 사용하여 redis에 삽입하는 코드입니다.outofDirectMemory exception with redisson

package redisson 

import java.io.File; 
import java.util.concurrent.atomic.AtomicInteger; 
import org.redisson.Redisson; 
import org.redisson.api.RBatch; 
import org.redisson.api.RMap; 
import org.redisson.api.RedissonClient; 
import org.redisson.config.Config; 


public class RedisTest extends Thread { 

    static RMap<String, String> dMap = null; 
    static RMap<String, String> wMap = null; 
    static RMap<String, String> mMap = null; 
    static RedissonClient redisson = null; 

    public static void main(String[] args) throws Exception { 

     Config config = Config.fromJSON(new File("C:\\Users\\neon-workspace\\RedisProject\\src\\main\\resources\\SingleNodeConfig.json")); 
      RedissonClient redisson = Redisson.create(config); 
      dMap = redisson.getMap("Daily"); 
      wMap = redisson.getMap("Weekly"); 
      mMap = redisson.getMap("Monthly"); 

      connectHbse(dMap,wMap,mMap,redisson); 
      redisson.shutdown(); 

    } 

    public static void connectHbse(RMap<String, String> dMap,RMap<String, String> wMap,RMap<String, String> mMap,RedissonClient redisson) { 
     int totalSize=500000; 
     int totalThread=2; 
     int chunkSize = totalSize/totalThread; 
     AtomicInteger total = new AtomicInteger(chunkSize); 
     RedisTest test1[] = new RedisTest[totalThread]; 
     for (int i = 0; i < test1.length; i++) { 
      test1[i] = new RedisTest(total,dMap,wMap,mMap,redisson); 
      total.set(total.intValue()+chunkSize); 
     } 
     long t1 = System.currentTimeMillis(); 
     for (int i = 0; i < test1.length; i++) { 
      test1[i].start(); 
     } 
     try { 
      for (int i = 0; i < test1.length; i++) { 
       test1[i].join(); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("Final Total Time Taken ::>>>>>>>>>>>>>>>>> " + ((System.currentTimeMillis() - t1))+"ms"); 
    } 

    private AtomicInteger total = null; 
    public RedisTest(AtomicInteger total,RMap<String, String> dMap,RMap<String, String> wMap,RMap<String, String> mMap,RedissonClient redisson) { 
     this.total = new AtomicInteger(total.intValue()); 
     this.dMap = dMap; 
     this.wMap = wMap; 
     this.mMap = mMap; 
     this.redisson = redisson; 
    } 

    public static int getRandomInteger(int maximum, int minimum) { 
     return ((int) (Math.random() * (maximum - minimum))) + minimum; 
    } 

    public void run() { 

     try { 

      long t1 = System.currentTimeMillis(); 
      dMap.clear(); 
      wMap.clear(); 
      mMap.clear(); 
      RBatch batch = redisson.createBatch(); 

      for (;total.decrementAndGet()>=0;) {  
       String dvalue = ""+getRandomInteger(100,200); 
       String wvalue = "" +getRandomInteger(200, 300); 
       String mvalue = "" +getRandomInteger(300, 400); 

       batch.getMap("Daily").fastPutAsync(""+total.get(), dvalue); 
       batch.getMap("Weekly").fastPutAsync(""+total.get(), wvalue); 
       batch.getMap("Monthly").fastPutAsync(""+total.get(), mvalue); 

        synchronized (total) { 
         if(total.get()%100==0) 
          System.out.println(total.get()+" Records in Seconds:::::" + ((System.currentTimeMillis() - t1))/1000); 
        } 
      } 
      batch.execute(); 

      System.out.println("Time Taken for completion::::: " + ((System.currentTimeMillis() - t1))+" by thread:::::"+Thread.currentThread().getName()); 
      System.out.println("Done !!!"); 
     } catch (Exception e) { 
      System.out.println("Done !!!" + e.getMessage()); 
      e.printStackTrace(); 
     } finally { 

     } 
    } 
} 

이 코드는 totalSize = 400000이 될 때까지 정상적으로 작동합니다. totalSize = 500000을 넣으면 다음 예외가 발생합니다.

io.netty.handler.codec.EncoderException: io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 939524096, max: 954466304) 
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125) 
    at org.redisson.client.handler.CommandBatchEncoder.write(CommandBatchEncoder.java:45) 
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738) 
    ... 25 more 
Caused by: io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 939524096, max: 954466304) 
    at io.netty.util.internal.PlatformDependent.incrementMemoryCounter(PlatformDependent.java:627) 
    at io.netty.util.internal.PlatformDependent.allocateDirectNoCleaner(PlatformDependent.java:581) 
    at io.netty.buffer.PoolArena$DirectArena.allocateDirect(PoolArena.java:764) 
    at io.netty.buffer.PoolArena$DirectArena.newChunk(PoolArena.java:740) 
    at io.netty.buffer.PoolArena.allocateNormal(PoolArena.java:244) 
    at io.netty.buffer.PoolArena.allocate(PoolArena.java:226) 
    at io.netty.buffer.PoolArena.reallocate(PoolArena.java:397) 
    at io.netty.buffer.PooledByteBuf.capacity(PooledByteBuf.java:118) 
    at io.netty.buffer.AbstractByteBuf.ensureWritable0(AbstractByteBuf.java:285) 
    at io.netty.buffer.AbstractByteBuf.ensureWritable(AbstractByteBuf.java:265) 
    at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1046) 
    at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1054) 
    at org.redisson.client.handler.CommandEncoder.writeArgument(CommandEncoder.java:169) 
    at org.redisson.client.handler.CommandEncoder.encode(CommandEncoder.java:110) 
    at org.redisson.client.handler.CommandBatchEncoder.encode(CommandBatchEncoder.java:52) 
    at org.redisson.client.handler.CommandBatchEncoder.encode(CommandBatchEncoder.java:32) 
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107) 
    ... 27 more 

하지만 약 7Gb RAM이 없습니다. 누군가이 예외가 발생하는 이유를 설명 할 수 있습니까?

답변

0

나는 나를 위해이 문제를 해결 한 -Xmx를 사용하여 JVM 인스턴스에 더 많은 메모리를 제공해야하는 것으로 보인다.