com.github.javaclub.toolbox.thread.memlimit.MemorySafeLinkedBlockingQueue Maven / Gradle / Ivy
/*
* @(#)MemorySafeLinkedBlockingQueue.java 2022-6-16
*
* Copyright (c) 2022. All Rights Reserved.
*
*/
package com.github.javaclub.toolbox.thread.memlimit;
import java.util.Collection;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.javaclub.Constants.MemCapacity;
/**
* Can completely solve the OOM problem caused by {@link java.util.concurrent.LinkedBlockingQueue},
* does not depend on {@link java.lang.instrument.Instrumentation} and is easier to use than
* {@link LinkedBlockingQueue} with Memory Safely policy.
*
* @see MemorySafeLinkedBlockingQueue
*/
public class MemorySafeLinkedBlockingQueue extends LinkedBlockingQueue {
private static final long serialVersionUID = 8032578371739960142L;
private static final Logger log = LoggerFactory.getLogger(MemorySafeLinkedBlockingQueue.class);
/**
* JVM可用内存大小默认保留值(16MB)
*/
private static final int JVM_RESERVED_MEM_DEFAULT = MemCapacity.intBytesOfMB(16);
/**
* 为JVM预设保留的空闲内存,当JVM剩余可用内存小于此值时,不允许往队列提交新Element
*/
private int maxFreeMemory;
public MemorySafeLinkedBlockingQueue() {
this(Integer.MAX_VALUE, JVM_RESERVED_MEM_DEFAULT);
}
public MemorySafeLinkedBlockingQueue(final int queueCapacity) {
this(queueCapacity, JVM_RESERVED_MEM_DEFAULT);
}
/**
* @param maxFreeMemory 为JVM兜底保留的空闲内存大小字节数(防止OOM)
*/
public MemorySafeLinkedBlockingQueue(final int queueCapacity, final int maxFreeMemory) {
super(queueCapacity);
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() {
return MemoryLimitCalculator.maxAvailable() > maxFreeMemory;
}
@Override
public void put(final E e) throws InterruptedException {
if (hasRemainedMemory()) {
super.put(e);
return;
}
log.warn("BlockingQueue can't accept more by memory limited.");
}
@Override
public boolean offer(final E e, final long timeout, final TimeUnit unit) throws InterruptedException {
if (hasRemainedMemory()) {
return super.offer(e, timeout, unit);
}
log.warn("BlockingQueue can't handle more by memory limited.");
return false;
}
@Override
public boolean offer(final E e) {
if (hasRemainedMemory()) {
return super.offer(e);
}
log.warn("BlockingQueue can't handle more by memory limited.");
return false;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy