Какой инструмент отладки может отображать внутренние строки?

Я ищу инструмент отладки, который может перечислить строки, которые были интернализованы? В идеале я хотел бы поставить отметку и иметь список строк, которые были добавлены после этой отметки.

Заранее спасибо.


person Guillaume Coté    schedule 30.05.2011    source источник
comment
@Ed Staub - я использую eclipse на компьютере с окном, но я компилирую с помощью ant на компьютере с Linux и работаю там. Почему ты спрашиваешь?   -  person Guillaume Coté    schedule 08.07.2011
comment
Не уверен, что это полезно: вы можете поместить средство форматирования деталей отладчика в String, которое покажет, интернировано ли оно, например: (this==this.intern())?("^"+toString()):toString(). Можете ли вы объяснить, для чего вам нужен инструмент? Это потому, что вы полагаетесь на проверку на равенство, или вы смотрите на использование памяти, или...   -  person Ed Staub    schedule 08.07.2011
comment
@Ed Staub - это интернирует всю строку. Я не смогу узнать, какие из них добавлены приложением, а какие отладчиком. Я не полагаюсь на проверку на равенство. Количество интернализированных строк растет в процессе, я пытаюсь понять, почему.   -  person Guillaume Coté    schedule 08.07.2011
comment
Ой, это была глупая идея! У вас происходит нестандартная загрузка классов? Если да, то это первое место, которое я бы посмотрел - большинство стажировок должно быть связано с загрузкой константных строк классов. Проверьте наличие нескольких экземпляров одного и того же объекта класса.   -  person Ed Staub    schedule 08.07.2011
comment
@Ed Staub - Нет, у меня нет нестандартной загрузки классов. Я использовал jmap, чтобы увидеть количество внутренних строк и количество загруженных классов. Classloaded почти не движется, но усваиваются сотни тысяч строк.   -  person Guillaume Coté    schedule 08.07.2011
comment
Вот еще одна техника, надеюсь, более полезная. Установите точку останова, которая будет срабатывать после инициализации, после того как ваше приложение должно перейти в устойчивое состояние. Когда он сработает, поставьте точку останова на входе метода в String.intern с большим числом — 100 или больше. Проверяйте стопку каждый раз, когда она попадает, чтобы выяснить, кто провоцирует всех стажеров. Предупреждение: точки останова метода ОЧЕНЬ медленные (в отличие от точек останова строки).   -  person Ed Staub    schedule 08.07.2011
comment
Небольшое улучшение: вместо использования счетчика просто время от времени вручную включайте точку останова, проверяйте стек, отключайте точку останова и продолжайте. Это даст образцы, которые находятся намного дальше друг от друга - с меньшей вероятностью все случайно укажут на что-то, что не является виновником, но в то время много интернировалось.   -  person Ed Staub    schedule 08.07.2011
comment
@Ed Staub - Спасибо за предложение использовать точку останова. Тем не менее, я получил несколько сотен тысяч звонков, которые абсолютно законны. Я еще не запускал приложение удаленным отладчиком, попробую изучить.   -  person Guillaume Coté    schedule 08.07.2011
comment
После того, как приложение разогреется, я ожидаю, что большинство стажеров будут подозрительными - учитывая проблему, которую вы описали. Шансы должны быть в вашу пользу, что вы быстро получите некоторое представление. Кстати... вы анализируете много XML с уникальными именами элементов или атрибутов? Я подозреваю, что может быть причиной этого.   -  person Ed Staub    schedule 08.07.2011


Ответы (2)


Возможно, самый простой способ — использовать программу просмотра байт-кода. Любая интернированная строка будет присутствовать в пуле констант файла класса, в который включен литерал строки. Например, в недавнем файле класса из другого вопроса StackOverflow, на который я ответил, в моем коде был следующий литерал строки: "sun.awt.noerasebackground". Это отображается в пуле констант как тип 'String_info'. Средство просмотра байт-кода (и редактор, будьте осторожны!), которым я пользуюсь, — это JBE. Загрузка JBE

person Josh    schedule 02.08.2011
comment
У вас есть URL-адрес документации по JBE? - person Guillaume Coté; 03.08.2011
comment
Это небольшой проект, и, насколько я знаю, у него нет документации. - person Josh; 07.08.2011

На недавней виртуальной машине Hotspot интернированные строки выглядят так же, как и любые другие — единственная разница в том, что базовый массив символов отслеживается виртуальной машиной (я думал, что у нее есть дополнительная ссылка JNI, но она не отображается в дампе YourKit — будет интересно исследовать)

Тем не менее, Yourkit обеспечивает проверку памяти на наличие дублирующихся строк, что, я считаю, делает то, что вам нужно. Если вы объедините его с «Trace Allocations», вы можете перейти прямо к коду, который выделил эти строки.

См. http://www.yourkit.com/docs/95/help/inspections_mem.jsp#duplicate_strings

--

Получить список строк, добавленных между двумя моментами времени, проще:

  1. Получите два дампа кучи с помощью jmap или вашего любимого профилировщика
  2. Сделайте разницу в кучах
  3. Показать все экземпляры класса String

Должно быть выполнимо с любым профилировщиком или даже jhat (если вы достаточно терпеливы). Если вы используете YourKit, вы можете использовать функцию закладки и сделать только один снимок кучи.

person ddimitrov    schedule 17.07.2011
comment
Проблема не в повторяющейся строке. Дублирование находится в куче памяти, которой у меня достаточно. Проблема в интернированной строке. Наличие списка всех строк не поможет, если я не вижу, какие из них интернированы, а какие нет. - person Guillaume Coté; 21.07.2011