开发者

how can I subclass ByteBuffer?

So the Java NIO architects didn't make a ByteBuffer interface, but rather a ByteBuffer class, which isn't a final class, but it has no package-public constructors, and therefore it can't be subclassed outside of its package. 开发者_JS百科Phooey. :P

I have a program that uses memory-mapped file byte buffers (obtained via FileChannel.map()) in a bunch of places, and I'm trying to track down a nasty bug where the file in question is left open because there is at least one ByteBuffer that isn't released to garbage collection.

I would like to create an InstrumentedByteBuffer class that looks like a byte buffer, but decorates a regular ByteBuffer (or its subclasses e.g. MappedByteBuffer) and keeps track of its existence (including new buffers created by duplicate() and slice()) -- that way I can keep my code intact that uses the ByteBuffer, I just have to decorate the original byte buffer.

Is there any way to do this (via reflection or proxies or whatever) to get around the private constructors? I don't need to ship this into a final product, I just need to use it temporarily to solve this bug.


I'm trying to track down a nasty bug where the file in question is left open because there is at least one ByteBuffer that isn't released to garbage collection

That doesn't make sense. An uncollected ByteBuffer won't stop a file being closed. You're barking up the wrong tree here. However there is a well-known problem with MappedByteBuffer whereby it is never garbage-collected, keeping the file effectively open. It's really a design problem: it has been known about for years but there is no real solution. The moral is don't use large numbers of MappedByteBuffers.


JMockit provides a convenient way of creating a mocked class. It may be of help in this case.

Mock the methods you are interested in, and let them do your bookkeeping and then call the original class' method.


I think you are on the wrong track. FileChannel.map() is broken by design because its limited to 2GB chunks and you can't control when the mapping should get picked up by the garbage collection. On Windows, this is a frequent cause for the application not being able to open the mapped file again.

So instead of making things even worse with byte code instruction or similar hacks, you should refactor your code to get rid of FileChannel.map(). The next programmer who has to maintain your code will be very thankful if you did. ;-)


I don't see why you need to subclass here. Why not use AOP? AspectJ seems perfect for the job. If you're really feeling ambitious, use Java Instrumentation and do some byte code engineering :P


Hmm -- I just ran across this: the JavaSpecialists newsletter 168 seems like it can produce a general-purpose delegation framework -- if a bit slow due to reflection.

Socket uses the strategy pattern for the actual communication and we are able to specify our own implementation. Thus all we would need to do is write our own strategy that counts the bytes flowing backwards and forwards. Unfortunately the standard strategy implementations are package access in the java.net.* package, so we are not able to use them directly. We certainly cannot subclass them, but we could call the methods with reflection. However, because the classes themselves are package access, we need to find the declared constructor, set that to be accessible and then instantiate it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜