fengyouchao / sockslib

A Java library of SOCKS5 protocol including client and server
Apache License 2.0
284 stars 104 forks source link

安卓设备内存溢出问题及解决方法 #6

Open forrestsocool opened 7 years ago

forrestsocool commented 7 years ago

It crashes due to a stack-over-flow problem everytime when I used the library as a socks5server running on Android device。Which is caused by the frequently allocated byte[] buffer using in StreamPipe.java。

I fixed this problem in two steps:

  1. reduce the byte[] buffer in StreamPipe.java to 256960
  2. use a BufferPool to allocate new buffer, witch can automatically deallocate memory when the buffer nums meet the setting max.

the BufferPool I used:

class BufferPool {
private static final int BUFFER_SIZE = 256960;     //缓冲包2M
private static final int BUFFER_MAX_NUM = 40;                   //缓冲池保留最大数量
private static final ConcurrentLinkedQueue<byte[]> buffers = new ConcurrentLinkedQueue<byte[]>();
private static AtomicInteger countCreated = new AtomicInteger(0);   //已创建的缓冲包个数

/**
 * 分配
 */
public static byte[] allocate() {
    byte[] result = buffers.poll();
    //创建新缓冲包
    if (result == null) {
        result = new byte[BUFFER_SIZE];

        //记录创建个数
        int count = countCreated.incrementAndGet();

        //日志
        if (count <= BUFFER_MAX_NUM) {
            logger.info("创建新的BufferPool缓冲池,已创建总数量:count={}", count);
        } else {
            logger.warn("创建新的BufferPool缓冲池,已创建总数量:count={}", count, new Throwable());
        }
    }
    return result;
}

/**
 * 回收
 *
 * @param buff
 */
public static void deallocate(byte[] buff) {
    //缓冲池已达上限
    if (buffers.size() >= BUFFER_MAX_NUM) return;
    //回收的缓冲大小必须正确
    if (buff.length != BUFFER_SIZE) return;

    //加回到池中
    buffers.add(buff);
}
}

Anyway, I didn't tested the performance influenced by the reduction of buffer size and nums。maybe there is another good way to make it runner better on Android.

Your code is Excellent !