Загрузка класса, который имеет только статические методы - PullRequest
2 голосов
/ 11 июня 2011

У меня есть класс MyClass, который имеет статическую переменную. Класс реализует что-то вроде синглтона (он имеет java.sql.DataSource в качестве статической переменной и имеет метод getConnection(), который проверяет, является ли переменная DataSource ненулевым, и если она пуста - получает соединение, иначе - возвращает dataSource.getConnection()) Когда я в первый раз вызываю метод MyClass.getConnection(), класс загружается в память и получается переменная DataSource. Будет ли этот класс оставаться в памяти во время работы программы, или он будет собирать мусор, когда поток управления программы выйдет за пределы метода, в котором был вызван MyClass.getConnection()? На самом деле я хочу знать, должен ли я получать объект Connection в каждом методе (получение объекта подключения - довольно длительная операция, не так ли?), Где я использую его или только один раз в каком-то месте?

1010 * редактировать * Это мой класс, который получает соединение

public class ResourceManager {

    private static DataSource dataSource;


    public static synchronized Connection getConnection() throws NamingException, SQLException {
        if (dataSource == null) {
            Locale.setDefault(Locale.ENGLISH);
            Context context = (Context) new InitialContext().lookup("java:comp/env");
            dataSource = (DataSource) context.lookup("jdbc/Project");
            context.close();
        }
        return dataSource.getConnection();
    }


    public static void close(Connection con) {
        if (con != null)
            try {
            con.close();
        } catch (SQLException ex) {
            Logger.getLogger(ResourceManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public static void close(ResultSet rs) {
        if (rs != null)
            try {
            rs.close();
        } catch (SQLException ex) {
            Logger.getLogger(ResourceManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public static void close(PreparedStatement stmt) {
        if (stmt != null)
            try {
            stmt.close();
        } catch (SQLException ex) {
            Logger.getLogger(ResourceManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

в этом классе я получаю соединение из пула котов

Итак, если в одном из методов я вызову ResourseManager.getConnection () и он получит источник данных, будет ли он тем же источником данных, когда я вызову этот метод через некоторое время или это будет GC?

P.S. Я использую методы close в блоках finally

Ответы [ 2 ]

2 голосов
/ 11 июня 2011

Останется ли этот класс в памяти, пока программа запущена или будет мусор собирают при контроле поток программы выйдет наружу метод где MyClass.getConnection () был вызван?

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

В долго работающих приложениях (например, приложениях Java EE) класс и загрузчик классов (как правило, уникальный существует для каждого приложения) не будут иметь права на сборку мусора, пока само приложение не будет закрыто.

Синглтон-паттерн и его влияние на ГХ

Сборка мусора классов, реализующих шаблон синглтона, является уникальной ситуацией. На класс по-прежнему ссылается его экземпляр, поэтому он никогда не будет иметь право на сборку мусора. Это может привести к проблемам, при которых сами загрузчики классов могут не собираться мусором, особенно во время перезапуска приложения в контейнере, что приводит к утечке памяти. Решение этой проблемы состоит в том, чтобы уничтожить экземпляр синглтона в прослушивателе контекста, который прослушивает событие уничтожения контекста (приложения).

Обновление № 2

Для обновленного вопроса:

На самом деле я хочу знать, должен ли я получать объект Connection в каждом методе (получение объекта подключения - это довольно длительная операция, не так ли?), Где я его использую или только один раз в каком-то месте?

Получение соединения стоит дорого, но только если вы управляете соединением. Вот почему вы используете источник данных, поддерживаемый пулом соединений. Каждый раз, когда вам нужно соединение, источник данных будет получать его из пула. Как только вы закончите с соединением, вы должны закрыть его, чтобы оно могло быть возвращено в пул. Мой совет - не выполнять преждевременную оптимизацию; пулы соединений являются фактом в современных приложениях Java EE, и серверы приложений выполняют достаточную оптимизацию, чтобы обеспечить здесь очень малую задержку. ИМХО, правильно настроенный пул даст вам лучшую производительность, чем класс, созданный вручную для централизованного доступа к объектам соединения.

0 голосов
/ 11 июня 2011

Когда вы имеете дело со статическими методами и т. Д., Они не принадлежат экземпляру. Как таковые, они не собирают мусор при сборе экземпляров. Вместо этого они остаются в памяти. Теоретически, они должны оставаться в памяти, пока рассматриваемое приложение не будет прекращено. Пока он продолжает работать, статические элементы остаются в памяти.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...