[#973] Use static IdleStateEvents to reduce GC pressure

This commit is contained in:
Norman Maurer 2013-01-23 17:34:27 +01:00
parent b9aaf9a167
commit 9da01417b2
2 changed files with 45 additions and 54 deletions

View File

@ -24,58 +24,32 @@ import io.netty.channel.Channel;
* @apiviz.has io.netty.handler.timeout.IdleState oneway - -
*/
public final class IdleStateEvent {
public static final IdleStateEvent FIRST_READER_IDLE_STATE_EVENT = new IdleStateEvent(IdleState.READER_IDLE, true);
public static final IdleStateEvent READER_IDLE_STATE_EVENT = new IdleStateEvent(IdleState.READER_IDLE, false);
public static final IdleStateEvent FIRST_WRITER_IDLE_STATE_EVENT = new IdleStateEvent(IdleState.WRITER_IDLE, true);
public static final IdleStateEvent WRITER_IDLE_STATE_EVENT = new IdleStateEvent(IdleState.WRITER_IDLE, false);
public static final IdleStateEvent FIRST_ALL_IDLE_STATE_EVENT = new IdleStateEvent(IdleState.ALL_IDLE, true);
public static final IdleStateEvent ALL_IDLE_STATE_EVENT = new IdleStateEvent(IdleState.ALL_IDLE, false);
private final IdleState state;
private final int count;
private final long durationMillis;
/**
* Create a new instance
*
* @param state the detailed idle state.
* @param count the count how often this kind of {@link IdleStateEvent} was fired before
* @param durationMillis the duration which caused the {@link IdleStateEvent} to get fired in milliseconds
*/
public IdleStateEvent(IdleState state, int count, long durationMillis) {
if (state == null) {
throw new NullPointerException("state");
}
if (count < 0) {
throw new IllegalStateException(String.format("count: %d (expected: >= 0)", count));
}
if (durationMillis < 0) {
throw new IllegalStateException(String.format(
"durationMillis: %d (expected: >= 0)", durationMillis));
}
private final boolean first;
private IdleStateEvent(IdleState state, boolean first) {
this.state = state;
this.count = count;
this.durationMillis = durationMillis;
this.first = first;
}
/**
* Returns the detailed idle state.
* Returns the idle state.
*/
public IdleState state() {
return state;
}
/**
* Return the count how often this kind of {@link IdleStateEvent} was fired before.
* Returns {@code true} if this was the first event for the {@link IdleState}
*/
public int count() {
return count;
}
/**
* Return the duration which caused the {@link IdleStateEvent} to get fired in milliseconds.
*/
public long durationMillis() {
return durationMillis;
}
@Override
public String toString() {
return state + "(" + count + ", " + durationMillis + "ms)";
public boolean isFirst() {
return first;
}
}

View File

@ -110,19 +110,19 @@ public class IdleStateHandler extends ChannelStateHandlerAdapter implements Chan
volatile ScheduledFuture<?> readerIdleTimeout;
volatile long lastReadTime;
int readerIdleCount;
private boolean firstReaderIdleEvent = true;
volatile ScheduledFuture<?> writerIdleTimeout;
volatile long lastWriteTime;
int writerIdleCount;
private boolean firstWriterIdleEvent = true;
volatile ScheduledFuture<?> allIdleTimeout;
int allIdleCount;
private boolean firstAllIdleEvent = true;
private volatile int state; // 0 - none, 1 - initialized, 2 - destroyed
/**
* Creates a new instance.
* Creates a new instance firing {@link IdleStateEvent}s.
*
* @param readerIdleTimeSeconds
* an {@link IdleStateEvent} whose state is {@link IdleState#READER_IDLE}
@ -147,7 +147,7 @@ public class IdleStateHandler extends ChannelStateHandlerAdapter implements Chan
}
/**
* Creates a new instance.
* Creates a new instance firing {@link IdleStateEvent}s.
*
* @param readerIdleTime
* an {@link IdleStateEvent} whose state is {@link IdleState#READER_IDLE}
@ -168,7 +168,6 @@ public class IdleStateHandler extends ChannelStateHandlerAdapter implements Chan
public IdleStateHandler(
long readerIdleTime, long writerIdleTime, long allIdleTime,
TimeUnit unit) {
if (unit == null) {
throw new NullPointerException("unit");
}
@ -258,7 +257,7 @@ public class IdleStateHandler extends ChannelStateHandlerAdapter implements Chan
@Override
public void inboundBufferUpdated(ChannelHandlerContext ctx) throws Exception {
lastReadTime = System.currentTimeMillis();
readerIdleCount = allIdleCount = 0;
firstReaderIdleEvent = firstAllIdleEvent = true;
ctx.fireInboundBufferUpdated();
}
@ -274,7 +273,7 @@ public class IdleStateHandler extends ChannelStateHandlerAdapter implements Chan
@Override
public void operationComplete(ChannelFuture future) throws Exception {
lastWriteTime = System.currentTimeMillis();
writerIdleCount = allIdleCount = 0;
firstWriterIdleEvent = firstAllIdleEvent = true;
}
});
@ -313,7 +312,7 @@ public class IdleStateHandler extends ChannelStateHandlerAdapter implements Chan
@Override
public void operationComplete(ChannelFuture future) throws Exception {
lastWriteTime = System.currentTimeMillis();
writerIdleCount = allIdleCount = 0;
firstWriterIdleEvent = firstAllIdleEvent = true;
}
});
ctx.sendFile(region, promise);
@ -393,8 +392,14 @@ public class IdleStateHandler extends ChannelStateHandlerAdapter implements Chan
readerIdleTimeout =
ctx.executor().schedule(this, readerIdleTimeMillis, TimeUnit.MILLISECONDS);
try {
channelIdle(ctx, new IdleStateEvent(
IdleState.READER_IDLE, readerIdleCount ++, currentTime - lastReadTime));
IdleStateEvent event;
if (firstReaderIdleEvent) {
firstReaderIdleEvent = false;
event = IdleStateEvent.FIRST_READER_IDLE_STATE_EVENT;
} else {
event = IdleStateEvent.READER_IDLE_STATE_EVENT;
}
channelIdle(ctx, event);
} catch (Throwable t) {
ctx.fireExceptionCaught(t);
}
@ -427,8 +432,14 @@ public class IdleStateHandler extends ChannelStateHandlerAdapter implements Chan
writerIdleTimeout = ctx.executor().schedule(
this, writerIdleTimeMillis, TimeUnit.MILLISECONDS);
try {
channelIdle(ctx, new IdleStateEvent(
IdleState.WRITER_IDLE, writerIdleCount ++, currentTime - lastWriteTime));
IdleStateEvent event;
if (firstWriterIdleEvent) {
firstWriterIdleEvent = false;
event = IdleStateEvent.FIRST_WRITER_IDLE_STATE_EVENT;
} else {
event = IdleStateEvent.WRITER_IDLE_STATE_EVENT;
}
channelIdle(ctx, event);
} catch (Throwable t) {
ctx.fireExceptionCaught(t);
}
@ -462,8 +473,14 @@ public class IdleStateHandler extends ChannelStateHandlerAdapter implements Chan
allIdleTimeout = ctx.executor().schedule(
this, allIdleTimeMillis, TimeUnit.MILLISECONDS);
try {
channelIdle(ctx, new IdleStateEvent(
IdleState.ALL_IDLE, allIdleCount ++, currentTime - lastIoTime));
IdleStateEvent event;
if (firstAllIdleEvent) {
firstAllIdleEvent = false;
event = IdleStateEvent.FIRST_ALL_IDLE_STATE_EVENT;
} else {
event = IdleStateEvent.ALL_IDLE_STATE_EVENT;
}
channelIdle(ctx, event);
} catch (Throwable t) {
ctx.fireExceptionCaught(t);
}