как я могу создать подкласс ByteBuffer? - PullRequest
10 голосов
/ 10 октября 2011

Таким образом, архитекторы Java NIO создали не интерфейс ByteBuffer, а класс ByteBuffer , который не является конечным классом, но не имеет конструкторов public-пакета и поэтому он не может быть разделен на подклассы вне своей упаковки. Phooey. : P

У меня есть программа, которая использует отображенные в памяти файловые байтовые буферы (полученные через FileChannel.map ()) в нескольких местах, и я пытаюсь отследить неприятную ошибку, когда рассматриваемый файл остается открытым, потому что есть по крайней мере один ByteBuffer, который не выпущен для сборки мусора.

Я бы хотел бы создать класс InstrumentedByteBuffer, который выглядит как байтовый буфер, но украшает обычный ByteBuffer (или его подклассы, например MappedByteBuffer) и отслеживает его существование (включая новые буферы, созданные duplicate() и slice()) - таким образом, я могу сохранить свой код без изменений, используя ByteBuffer, мне просто нужно украсить оригинальный буфер байтов.

Есть ли способ сделать это (с помощью рефлексии или прокси или как угодно), чтобы обойти частные конструкторы? Мне не нужно отправлять это в конечный продукт, мне просто нужно временно использовать его для устранения этой ошибки.

Ответы [ 5 ]

2 голосов
/ 18 октября 2011

JMockit предоставляет удобный способ создания ложного класса. Это может помочь в этом случае.

Думайте о методах, которые вас интересуют, и позвольте им вести бухгалтерию, а затем вызывайте оригинальный метод класса .

2 голосов
/ 11 октября 2011

Я пытаюсь отследить неприятную ошибку, когда файл оставлен открытым, потому что есть по крайней мере один байтбуфер, который не освобожден в сборщик мусора

Это не имеет смысла. Несобранный ByteBuffer не остановит закрытие файла. Вы лаете не на то дерево. Однако существует известная проблема с MappedByteBuffer, при которой it никогда не собирается сборщиком мусора, что делает файл эффективно открытым. Это действительно проблема дизайна: об этом известно уже много лет, но реального решения не существует. Мораль не использовать большое количество MappedByteBuffers.

0 голосов
/ 23 апреля 2012

Я думаю, что вы на неправильном пути. FileChannel.map () по своему дизайну не работает, поскольку он ограничен кусками в 2 ГБ, и вы не можете контролировать, когда сопоставление должно собираться сборщиком мусора. В Windows это частая причина того, что приложение не может снова открыть сопоставленный файл.

Таким образом, вместо того, чтобы еще больше ухудшить ситуацию с помощью инструкций байтового кода или подобных хаков, вам следует провести рефакторинг своего кода, чтобы избавиться от FileChannel.map (). Следующий программист, который должен поддерживать ваш код, будет очень благодарен, если вы это сделаете. ; -)

0 голосов
/ 18 октября 2011

Хм - я только что натолкнулся на это: Рассылка JavaSpecialists 168 похоже, что она может создать универсальную структуру делегирования - если она немного медленная из-за отражения.

Socket использует шаблон стратегии для фактического взаимодействия, и мы можем указать нашу собственную реализацию.Таким образом, все, что нам нужно сделать, это написать нашу собственную стратегию, которая подсчитывает байты, текущие взад и вперед.К сожалению, стандартные реализации стратегии представляют собой пакетный доступ в пакете java.net. *, Поэтому мы не можем использовать их напрямую.Мы, конечно, не можем разделить их на подклассы, но мы могли бы вызывать методы с отражением.Однако, поскольку сами классы имеют доступ к пакету, нам нужно найти объявленный конструктор, установить его как доступный, а затем создать его экземпляр.

0 голосов
/ 11 октября 2011

Я не понимаю, зачем вам здесь нужен подкласс.Почему бы не использовать АОП? AspectJ кажется идеальным для работы.Если вы действительно чувствуете себя честолюбивым, используйте Java Instrumentation и сделайте несколько байт-кода: P

...