正在加载仅具有静态方法的类 [英] Loading class which have only static methods

查看:106
本文介绍了正在加载仅具有静态方法的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有静态变量的类MyClass.类实现单例形式的smth(它具有java.sql.DataSource作为静态变量,并具有方法getConnection(),该方法检查DataSource变量是否不为null以及是否为null-获取连接,否则-返回dataSource.getConnection()) 当我第一次调用MyClass.getConnection()方法时,该类将加载到内存中并获得DataSource变量.此类在程序运行时会保留在内存中,还是当程序的控制流退出调用MyClass.getConnection()的方法之外时会被垃圾回收? 其实我想知道我是否必须在每种方法中都获得连接对象(获得连接对象是相当长的操作,不是吗?)我在哪里使用它或在某个地方仅使用一次?

I have a class MyClass that has a static variable. Class implements smth like singleton(it has java.sql.DataSource as static variable and has method getConnection() which checks whether DataSource variable is not null and if it is null - obtains the connection, else - return dataSource.getConnection()) When I call MyClass.getConnection() method for the first time the class is loaded to the memory and DataSource variable is obtained. Will this class stay in memory while the program is running or it will be garbage collected when the control flow of the program will exit outside the method where MyClass.getConnection() was invoked? Actually I want to know whether I have to obtain Connection object in each method(obtaining connection object is rather long operation, isn't it?) where I use it or only once in some place?

修改 这是我的获得联系的班级

edit This is my class that obtains a connection

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);
        }
    }
}

在本课程中,我从tomcat池获取连接

in this class I obtain connection from tomcat pool

因此,如果在一种方法中我调用ResourseManager.getConnection()并获取了数据源,那么经过一段时间后调用此方法时,它将是同一数据源吗?还是将是GC?

So, if in one method I call ResourseManager.getConnection() and it obtains the datasource, will it be the same datasource when I call this method after some time passed or it will be GC?

P.S.我在finally块中使用了close方法

P.S. I use close methods in finally blocks

推荐答案

此类会保留在内存中吗? 该程序正在运行,否则它将 垃圾收集时的控制 程序流程将退出外部 方法在哪里 MyClass.getConnection()被调用了吗?

Will this class stay in memory while the program is running or it will be garbage collected when the control flow of the program will exit outside the method where MyClass.getConnection() was invoked?

Class对象将像其他任何对象一样有资格进行垃圾回收-当不存在对Class对象的引用时.通常,这些引用由首先加载Class的ClassLoader持有.因此,只要引用该类的类加载器处于使用状态,该类就会保留下来.在方法执行后,除非调用者创建了Classloader,并且对该类加载器的引用不再存在,否则它将不会被卸载.

Class objects will become eligible for garbage collection just like any other object - when no references exist to the Class objects. Typically, these references are held by the ClassLoader that loaded the Class in the first place. So, the class will stay as long as the Classloader that references it, is in use. It will not be unloaded after method execution, unless the Classloader was created by the caller, and the reference to the classloader no longer exists.

在长时间运行的应用程序(如Java EE应用程序)中,类和类加载器(每个应用程序通常都存在唯一的类)将不符合垃圾回收的要求,直到应用程序本身关闭.

In long running applications (like Java EE applications), the class and the classloader (a unique one will typically exist for every application) will not be eligible for garbage collection, until the application itself is brought down.

单例模式及其对GC的影响

实现单例模式的类的垃圾回收是一种独特的情况.该类将继续由其实例引用,因此它将永远不符合进行垃圾收集的条件.这可能会导致类加载器本身可能无法被垃圾回收的问题,尤其是在容器中重新启动应用程序期间,从而导致内存泄漏.防止此类问题的解决方案是在侦听上下文(应用程序)破坏事件的上下文侦听器中销毁单例实例.

The garbage collection of classes that implement the singleton pattern is a unique situation. The class continues to be referenced by its instance, so it will never be eligible for garbage collection. This could lead to problems where the classloaders themselves may not be garbage collected, especially during application restarts in a container, thus leading to a memory leak. The solution to prevent such a problem, is to destroy the singleton instance in a context listener that listens for the context (application) destruction event.

更新#2

对于更新的问题:

实际上,我想知道是否必须在每种方法中使用连接对象(获取连接对象是相当长的操作,不是吗?),在我使用它的地方还是只在某个地方使用它一次?

Actually I want to know whether I have to obtain Connection object in each method(obtaining connection object is rather long operation, isn't it?) where I use it or only once in some place?

获得连接很昂贵,但前提是您要管理连接.这就是为什么您使用由连接池支持的数据源的原因.每次需要连接时,数据源都会从池中获取一个连接.一旦完成连接,就应该关闭它,以便可以将其返回到池中.我的建议是不要执行过早的优化.连接池是现代Java EE应用程序中的一个事实,并且应用程序服务器执行足够的优化以确保此处的延迟很小.恕我直言,经过适当调整的池将比为集中访问连接对象而创建的手工制作的类提供更好的性能.

Obtaining a connection is expensive, but only if you manage the connection. That's why you use a datasource backed by a connection pool. Everytime you need a connection, the datasource will fetch one from the pool. Once you are done with the connection, you should close it, so that it can be returned to the pool. My advice is to not perform premature optimizations; connection pools are a fact in modern Java EE applications, and application servers perform enough optimization to ensure that there is very little latency here. IMHO, a properly tuned pool will give you better performance than a hand-crafted class put in place to centralize access to connection objects.

这篇关于正在加载仅具有静态方法的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆