Pull to refresh

Comments 10

Спасибо за статью, интересно. Есть вопрос: загрузка классов идет в один поток? Если нет, то ClassTransformer может возвращать неверные данные.
Загрузка идет в один поток. Иначе не работал бы static initializer, например. В JLS написано.
А не могли бы Вы указать конкретное место в JLS, где это написано?
Почитал JLS.
Я не прав, в JLS не указывается, что загрузка идет обязательно в один поток.

Трансформер, из документации, срабатывает не в момент загрузки класса, а в магической инициализации класса нативным методом defineClass1, в синхронизированном по дефолту блоке loadClass.
Получается, если в приложении больше 1 потока и больше одного кастомного класслоадера грузят классы параллельно (обычно такое происходит намеренно), может получиться, что defineClass от разных класслоадеров будут вызываться из разных потоков.
Доступ к статическому count не защищен барьером на чтение/запись, будет гонка независимо от того, как реализованы класслоадеры.

Вообще, конечно, без эксперимента сложно уверенно судить о потокобезопасности трансформера. Лезть глубоко в jvm охоты нет.
private static final AtomicInteger count = new AtomicInteger();
...
System.out.println(... count.incrementAndGet());
Атомик как раз и есть барьер на чтение и запись с гарантиями. Если такого барьера у переменной нет, как у count в приведенном классе ClassTransformer, то уверенно судить о потокобезопасности нельзя.
А ещё Java Agent можно инъектировать в уже работающий процесс — Attach API.
> AgentCounter который будет выводить имя загружаемого класс и подсчитывать кол-во загруженных классов
А есть ли способ подсчитывать количество экземпляров данного класса

Всегда очень интересовало как выяснить: «Кто столько создал столько строк или int[], а найти родителя этих блоков?»
Возможно это решено уже с помощью какого-то уже существующего агента или отладчика?
Для этого есть профайлеры. Например YourKit Java Profiler. Из бесплатного, например Eclipse Memory Analyzer Tool.
Sign up to leave a comment.

Articles