Используя текущий класс в объявлении статического метода Java

В конечном итоге у вас всегда есть конечный максимум кучи для использования независимо от того, на какой платформе вы работаете. В Windows 32 бит это примерно 2GB (не куча, а общий объем памяти на процесс). Просто так получается, что Java решает уменьшить размер по умолчанию (предположительно, так, чтобы программист не мог создавать программы с распределенным выделением памяти, не сталкиваясь с этой проблемой и не проверяя, что именно они делают).

Таким образом, учитывая, что есть несколько подходов, которые вы можете использовать, чтобы определить, какой объем памяти вам нужен, или уменьшить объем используемой памяти. Одной из распространенных ошибок в языках сборки мусора, таких как Java или C #, является сохранение ссылок на объекты, которые вы больше не используете , или выделение множества объектов, когда вы можете использовать их вместо этого. Пока объекты имеют ссылку на них, они будут продолжать использовать пространство кучи, поскольку сборщик мусора не удалит их.

В этом случае вы можете использовать профилировщик памяти Java, чтобы определить, какие методы в вашей программе выделяют большое количество объектов, а затем определить, есть ли способ убедиться, что на них больше нет ссылок, или не выделять их в первое место. Одним из вариантов, который я использовал в прошлом, является «JMP» http://www.khelekore.org/jmp/ .

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

В общем, если вы не можете гарантировать, что ваша программа будет работать в некотором конечном объеме памяти (возможно, в зависимости от размера ввода), вы всегда столкнетесь с этой проблемой. Только после исчерпания всего этого вам нужно будет изучить кэширование объектов на диск и т. Д. В этот момент у вас должна быть очень веская причина сказать «мне нужен Xgb памяти» для чего-то, и вы не сможете обойти это, улучшив ваши алгоритмы или шаблоны распределения памяти. Как правило, это будет иметь место только в случае алгоритмов, работающих с большими наборами данных (например, с базой данных или какой-либо программой научного анализа), и тогда становятся полезными такие методы, как кэширование и ввод-вывод в память.

9
задан Chris Nelson 2 July 2009 в 18:23
поделиться

2 ответа

К сожалению, нет более простого способа, если вы находитесь в статическом контексте (как вы здесь). Если бы регистратором была переменная экземпляра, вы могли бы использовать getClass () , но тогда вам придется беспокоиться о подклассах.

В этом конкретном случае альтернативой является использование log5j ] вместо этого. log5j - это оболочка для log4j с удобными методами, такими как getLogger () , которые определяют правильный класс, поднимаясь по стеку. Таким образом, ваш код будет выглядеть следующим образом:

import com.spinn3r.log5j.Logger;
class myClass {
    private static final Logger logger = Logger.getLogger();
    ...
}

И вы можете без проблем скопировать и вставить одно и то же объявление во все свои классы.

8
ответ дан 4 December 2019 в 11:43
поделиться

Я не удержался.

Вот реализация того, что относится к mmyers, но самодельное :)

Обычно вы генерируете исключение и получаете второй элемент стека, чтобы получить имя класса.

Я все еще думаю, что лучше иметь его как элемент экземпляра.

:)

package some.utility.packagename;   
import java.util.logging.Logger;

import some.other.packagename.MyClass;

public class LoggerFactory {
    public static Logger getLogger() {
        StackTraceElement [] s = new RuntimeException().getStackTrace();
        return Logger.getLogger( s[1].getClassName() );
    }
    public static void main (String [] args) {
        MyClass a = new MyClass();
    }
}

Использование:

package some.other.packagename;
import java.util.logging.Logger;

import static some.utility.packagename.LoggerFactory.getLogger;

public class MyClass {

    private static final Logger logger = getLogger();
    static{
         System.out.println(MyClass.logger.getName());
    }

}
6
ответ дан 4 December 2019 в 11:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: