Netty:ByteBuf的资源释放方法

说明

io.netty.buffer.ByteBuf实现了io.netty.util.ReferenceCounted接口,需要显式释放。当ByteBuf被实例化后,它的引用计数是1。

调用ByteBuf对象的release方法释放:

  • ByteBuf的release()方法使引用计数减少1。只有当执行以后引用计数减少到0,该函数才返回true。当ByteBuf的引用计数减少到0时,ByteBuf会被释放。
  • 当ByteBuf的引用计数是0时,再执行release()方法会抛出IllegalReferenceCountException异常。

调用ReferenceCountUtil的方法释放:

  • release(Object msg):如果要被释放的对象msg实现了ReferenceCounted接口,那么内部会调用该对象的release()方法,并返回执行release()方法的结果。如果要被释放的对象msg没有实现ReferenceCounted接口,那么直接返回false。

代码示例

执行ByteBuf的release()返回结果观察

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Demo {

	public static void main(String[] args) {
		// 创建一个ByteBuf
		ByteBuf buf = Unpooled.buffer();
		// 引用计数加1
		buf.retain();
		
		// 此时的引用计数是2
		System.out.println("buf.refCnt: " + buf.refCnt());
		// 此时执行buf.release()返回false,因为执行以后的引用计数变成1
		System.out.println("buf.release: " + buf.release());
		// 此时的引用计数是1
		System.out.println("buf.refCnt: " + buf.refCnt());
		System.out.println("buf.release: " + buf.release());
		// 此时执行buf.release()返回true,因为执行以后的引用计数变成0
		System.out.println("buf.refCnt: " + buf.refCnt());		
	}

}

运行输出:

buf.refCnt: 2
buf.release: false
buf.refCnt: 1
buf.release: true
buf.refCnt: 0

ByteBuf的引用计数是0时,再执行release()方法会抛出IllegalReferenceCountException异常

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Demo {

	public static void main(String[] args) {
		// 创建一个ByteBuf
		ByteBuf buf = Unpooled.buffer();
		
		// 此时的引用计数是1
		System.out.println("buf.refCnt: " + buf.refCnt());
		// 此时执行buf.release()返回true,因为执行以后的引用计数变成0
		System.out.println("buf.release: " + buf.release());
		// 此时的引用计数是0
		System.out.println("buf.refCnt: " + buf.refCnt());
		// ByteBuf的引用计数已经变成0,再执行release()函数会抛出IllegalReferenceCountException异常
		System.out.println("buf.release: " + buf.release());
	}

}

运行结果:

buf.refCnt: 1
buf.release: true
buf.refCnt: 0
Exception in thread "main" io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
	at io.netty.util.internal.ReferenceCountUpdater.toLiveRealRefCnt(ReferenceCountUpdater.java:83)
	at io.netty.util.internal.ReferenceCountUpdater.release(ReferenceCountUpdater.java:148)
	at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:101)
	at com.thb.Demo.main(Demo.java:19)

调用ReferenceCountUtil的release(Object msg)方法释放

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.ReferenceCountUtil;

public class Demo {

	public static void main(String[] args) {
		// 创建一个ByteBuf
		ByteBuf buf = Unpooled.buffer();
		
		// 此时的引用计数是1
		System.out.println("buf.refCnt: " + buf.refCnt());
		// 此时执行ReferenceCountUtil.release(buf)返回true,因为执行以后的引用计数变成0
		System.out.println("ReferenceCountUtil.release: " + ReferenceCountUtil.release(buf));
		// 此时的引用计数是0
		System.out.println("buf.refCnt: " + buf.refCnt());
	}

}

运行输出:

buf.refCnt: 1
ReferenceCountUtil.release: true
buf.refCnt: 0

用ReferenceCountUtil的release(Object msg)释放一个引用计数为0的对象,抛出异常

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.ReferenceCountUtil;

public class Demo {

	public static void main(String[] args) {
		// 创建一个ByteBuf
		ByteBuf buf = Unpooled.buffer();
		
		// 此时的引用计数是1
		System.out.println("buf.refCnt: " + buf.refCnt());
		// 此时返回true,因为执行以后的引用计数变成0
		System.out.println("ReferenceCountUtil.release: " + ReferenceCountUtil.release(buf));
		// 此时的引用计数是0
		System.out.println("buf.refCnt: " + buf.refCnt());
		
		// 抛出异常,因为在执行调用前,buf当前的引用计数已经是0了
		System.out.println("ReferenceCountUtil.release: " + ReferenceCountUtil.release(buf));
	}

}

运行输出:

buf.refCnt: 1
Exception in thread "main" io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
	at io.netty.util.internal.ReferenceCountUpdater.toLiveRealRefCnt(ReferenceCountUpdater.java:83)
	at io.netty.util.internal.ReferenceCountUpdater.release(ReferenceCountUpdater.java:148)
	at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:101)
	at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:90)
	at com.thb.Demo.main(Demo.java:21)
ReferenceCountUtil.release: true
buf.refCnt: 0

用ReferenceCountUtil的release(Object msg)方法释放一个没有实现ReferenceCounted接口的对象,结果为false

package com.thb;

import io.netty.util.ReferenceCountUtil;

public class Demo {

	public static void main(String[] args) {
		String msg = "hello";
		
		// 此时返回false,因为对象是String类型,没有实现ReferenceCounted接口
		System.out.println("ReferenceCountUtil.release: " + ReferenceCountUtil.release(msg));
	}

}

运行输出:
在这里插入图片描述

你可能感兴趣的:(java,开发语言,Netty)