Санкт-Петербургская группа тестирования JVM


« Мониторинг состояния... | Main | Верификация байт-код... »
20070116 вторник Январь 16, 2007

DTrace: осторожно с глобальными переменными В DTrace есть 3 вида переменных:

  1. глобальные (global)—доступны везде.
  2. локальные в рамках потока (thread-local)—переменные определяются в области, локальной для каждого потока ОС и как следствие доступны в пробах, срабатываемых в рамках этих потоков. Доступ к этим переменным осуществляется с помощью префикса self->.
  3. локальные в рамках пробы (clause-local)—переменные доступны только в рамках определенных действий для конкретной пробы. В каком-то смысле эти переменные напоминают статические переменные в языке C, определенные в рамках функции. Доступ к этим переменным осуществляется с помощью префикса this->.

В общем-то из названий переменных сценарии использования различных типов переменных вполне очевидны. Хочется обратить внимание на то, что глобальные переменные не являются MP-safe (их использование небезопасно в многопроцессорных системах). Т.е., если проба срабатывает на нескольких процессорах одновременно (в свою очередь в рамках различных потоков) и в рамках действия для этой пробы увеличивается значение некой глобальной переменной, то атомарность этих действий не гарантируется и, как следствие, значение переменной может оказаться неверным.

Для демонстрации рассмотрим пример с использванием пробы hotspot:::object-alloc.

Напишем небольшую Java програму (ObjectAllocator.java), которая будет создавать 100.000 объектов типа ObjectToAlloc в 10 параллельных потоках:

class ObjectToAlloc { }

class ObjectAllocatorThread extends Thread {

static final int OBJECTS_CNT = 10000;

ObjectAllocatorThread(String name) {
super(name);
}

public void run() {
// создаем объекты
for (int i=0; i < OBJECTS_CNT; i++)
new ObjectToAlloc();
}
}

public class ObjectAllocator {

static final int THREADS_CNT = 10;

static public void main(String[] args) throws Exception {

ObjectAllocatorThread[] threads = new ObjectAllocatorThread[THREADS_CNT];

// создаем потоки
for (int i=0; i < THREADS_CNT; i++)
threads[i] = new ObjectAllocatorThread("ObjectAllocatorThread_" + i);

// запускаем потоки
for (int i=0; i < THREADS_CNT; i++)
threads[i].start();

// ждем завершения потоков
for (int i=0; i < THREADS_CNT; i++)
threads[i].join();

}
}

Теперь напишем D-скрипт object_allocation_stat.d, который будет считать сколько объектов типа ObjectToAlloc было создано в рамках Java программы.

#!/usr/sbin/dtrace -Zs

#pragma D option quiet

long long ALLOCATED_OBJECTS_CNT;

hotspot$target:::object-alloc
{
self->str_ptr = (char*) copyin(arg1, arg2+1);
self->str_ptr[arg2] = '\0';
self->class_name = (string) self->str_ptr;
}

hotspot$target:::object-alloc
/ self->class_name == "ObjectToAlloc" /
{
ALLOCATED_OBJECTS_CNT ++;

@allocs_count[tid] = count();
}

:::END
{
printf("%10s %10s\n", "thread", "objects");
printa("%10d %10@d\n", @allocs_count);

printf("\nALLOCATED_OBJECTS_CNT: %d\n", ALLOCATED_OBJECTS_CNT);
}
Для демонстрации некоректности значения глобальной переменной ALLOCATED_OBJECTS_CNT отдельно считаем количество объектов, созданных в рамках конкретного потока и записываем значение в ассоциативный массив allocs_count (ключ = идентификатор потока).

Компилируем ObjectAllocator.java и делаем object_allocation_stat.d исполняемым.

% $JDK6_HOME/javac ObjectAllocator.java
% chmod +x object_allocation_stat.d

Запускаем object_allocation_stat.d и видим, что значение глобальной переменной ALLOCATED_OBJECTS_CNT совсем не 100000.

% ./object_allocation_stat.d -c "$JDK6_HOME/java -XX:+ExtendedDTraceProbes ObjectAllocator"

thread objects
13 10000
14 10000
15 10000
16 10000
17 10000
18 10000
19 10000
20 10000
21 10000
22 10000

ALLOCATED_OBJECTS_CNT: 94007

Ошибка? Нет.

Со слов автора DTrace, реализовать корректную поддержку глобальных переменных DTrace в много-процессорном окружении практически невозможно. По-видимому, дело в том, что такая реализация скажется на производительности даже если DTrace не используется.

Так что будьте внимательны при использовании глобальных переменных!

Е. П. опубликовал vmrobot ( янв 16 2007, 06:09:29 PM MSK ) Permalink Комментарии [0]

Trackback URL: http://blogs.sun.com/vmrobot/entry/dtrace_%D0%BE%D1%81%D1%82%D0%BE%D1%80%D0%BE%D0%B6%D0%BD%D0%BE_%D1%81_%D0%B3%D0%BB%D0%BE%D0%B1%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%BC%D0%B8_%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%BC%D0%B8
Комментарии:

Опубликовать комментарий:

Имя
E-Mail:
URL:

Ваш комментарий:

HTML Syntax: Отключен

Хиты страниц за сегодня: 129