Я использую APC и могу засвидетельствовать, что он может существенно уменьшить ЦП и нагрузку ввода-вывода на сервер приложений при поддержании высокого уровня удачного обращения в кэш. Это не только сохраняет Вас от необходимости скомпилировать, это может сохранить Вас от необходимости считать php файлы из диска вообще. (т.е. байт-коды подаются непосредственно от оперативной памяти, таким образом, это супер быстро), Это понижает скорость для рендеринга единственной страницы и увеличивает запросы в секунду сервер может обработать.
, Если Вы используете Redhat или CentOS, устанавливая APC, супер просто:
yum install php-devel httpd-devel php-pear
pecl install apc
echo "extension=apc.so" > /etc/php.d/apc.ini
# if you're using SELinux:
chcon "system_u:object_r:textrel_shlib_t" /usr/lib/php/modules/apc.so
/etc/init.d/httpd restart
Вы спросили об оборотных сторонах. Единственный недостаток - то, что требуется некоторая память. Значение по умолчанию на APC составляет 30 МБ, но это может быть скорректировано, и стоимость определенной памяти больше, чем платежи за себя с увеличенной скоростью и показателем отклика.
Прежде всего, давайте обсудим, что такое «прямая ссылка» и почему она плохая. Прямая ссылка - это ссылка на переменную, которая еще не была инициализирована, и она не ограничивается только статическими инициализаторами. Это плохо просто потому, что, если они позволят, они дадут нам неожиданные результаты. Взгляните на этот фрагмент кода:
public class ForwardRef {
int a = b; // <--- Illegal forward reference
int b = 10;
}
Что должно быть j при инициализации этого класса? Когда класс инициализируется, инициализации выполняются в порядке от первого до последнего. Следовательно, можно ожидать, что строка
a = b;
будет выполняться до:
b = 10;
Во избежание такого рода проблем разработчики Java полностью запретили такое использование прямых ссылок.
РЕДАКТИРОВАТЬ
это поведение определяется разделом 8.3.2.3 Спецификаций языка Java :
Объявление члена должно появиться перед его использованием, только если член является экземпляром ( соответственно статическое) поле класса или интерфейса C и выполняются все следующие условия:
Использование происходит в экземпляре (соответственно статическом) инициализаторе переменной C или в экземпляре (соответственно статическом) инициализаторе C.
Использование не находится в левой части присвоения.
C - это самый внутренний класс или интерфейс, охватывающий использование.
Ошибка времени компиляции возникает, если любое из трех требований выше не выполнено.
попробуйте следующее:
class YourClass {
static {
myField = new HashSet<String>();
YourClass.myField.add("test");
}
private static Set<String> myField;
}
он должен компилироваться без ошибок в соответствии с JLS ...
(не особо помогает, или?)
В Java все инициализаторы, статические или другие, оцениваются в том порядке, в котором они появляются в определении класса.
См. Правила для прямых ссылок в JLS . Вы не можете использовать прямые ссылки, если:
Чтобы уточнить ответ DFA:
Я думаю, что вас сбивает с толку правило «левой стороны» во втором пункте в JLS 8.2.3.2. В вашей инициализации myField находится слева. В вашем вызове для добавления он находится справа. Код здесь неявно:
boolean result = myField.add('test')
Вы не оцениваете результат, но компилятор по-прежнему действует так, как будто он есть. Вот почему ваша инициализация проходит, а ваш вызов add () терпит неудачу.
Что касается , почему это так, я понятия не имею. Насколько я знаю, это вполне может быть сделано для удобства разработчиков JVM.
Я думаю, что вызов метода проблематичен, потому что компилятор не может определить, какой метод add ()
использовать без ссылочного типа для myField
.
Во время выполнения используемый метод будет определяться типом объекта, но компилятор знает только о ссылочном типе.