class MemorySafeLinkedBlockingQueue<E> extends VariableLinkedBlockingQueue<E> {

    private static final long serialVersionUID = 8032578371739960142L;

    public static final int THE_16_MB = 16 * 1024 * 1024;

    private int maxFreeMemory;

    public MemorySafeLinkedBlockingQueue() {
        this(THE_16_MB);
    }

    public MemorySafeLinkedBlockingQueue(final int maxFreeMemory) {
        super(Integer.MAX_VALUE);
        this.maxFreeMemory = maxFreeMemory;
    }

    public MemorySafeLinkedBlockingQueue(final int capacity, final int maxFreeMemory) {
        super(capacity);
        this.maxFreeMemory = maxFreeMemory;
    }

    public MemorySafeLinkedBlockingQueue(final Collection<? extends E> c, final int maxFreeMemory) {
        super(c);
        this.maxFreeMemory = maxFreeMemory;
    }

    /**
     * set the max free memory.
     *
     * @param maxFreeMemory the max free memory
     */
    public void setMaxFreeMemory(final int maxFreeMemory) {
        this.maxFreeMemory = maxFreeMemory;
    }

    /**
     * get the max free memory.
     *
     * @return the max free memory limit
     */
    public int getMaxFreeMemory() {
        return maxFreeMemory;
    }

    /**
     * determine if there is any remaining free memory.
     *
     * @return true if has free memory
     */
    public boolean hasRemainedMemory() {<FILL_FUNCTION_BODY>}

    @Override
    public void put(final E e) throws InterruptedException {
        if (hasRemainedMemory()) {
            super.put(e);
        }
    }

    @Override
    public boolean offer(final E e, final long timeout, final TimeUnit unit) throws InterruptedException {
        return hasRemainedMemory() && super.offer(e, timeout, unit);
    }

    @Override
    public boolean offer(final E e) {
        return hasRemainedMemory() && super.offer(e);
    }
}

        if (MemoryLimitCalculator.maxAvailable() > maxFreeMemory) {
            return true;
        }
        throw new RejectedExecutionException("No more memory can be used.");
    
<methods>public void <init>() ,public void <init>(int) ,public void <init>(Collection<? extends E>) ,public void clear() ,public boolean contains(java.lang.Object) ,public int drainTo(Collection<? super E>) ,public int drainTo(Collection<? super E>, int) ,public Iterator<E> iterator() ,public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException,public boolean offer(E) ,public E peek() ,public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException,public E poll() ,public void put(E) throws java.lang.InterruptedException,public int remainingCapacity() ,public boolean remove(java.lang.Object) ,public void setCapacity(int) ,public int size() ,public Spliterator<E> spliterator() ,public E take() throws java.lang.InterruptedException,public java.lang.Object[] toArray() ,public T[] toArray(T[]) ,public java.lang.String toString() <variables>private int capacity,private final java.util.concurrent.atomic.AtomicInteger count,transient Node<E> head,private transient Node<E> last,private final java.util.concurrent.locks.Condition notEmpty,private final java.util.concurrent.locks.Condition notFull,private final java.util.concurrent.locks.ReentrantLock putLock,private static final long serialVersionUID,private final java.util.concurrent.locks.ReentrantLock takeLock