gpt4 book ai didi

java - 加载只有静态方法的类

转载 作者:行者123 更新时间:2023-11-30 09:48:18 25 4
gpt4 key购买 nike

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

编辑这是我获取连接的类

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 池中获取连接

那么,如果在一个方法中我调用了 ResourseManager.getConnection() 并且它获得了数据源,那么当我在一段时间后调用这个方法时它会是同一个数据源还是会被 GC?

附言我在 finally block 中使用关闭方法

最佳答案

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?

类对象将像任何其他对象一样有资格进行垃圾回收 - 当不存在对类对象的引用时。通常,这些引用由首先加载类的类加载器保存。因此,只要引用它的类加载器在使用中,该类就会一直存在。它不会在方法执行后被卸载,除非类加载器是由调用者创建的,并且对类加载器的引用不再存在。

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

单例模式及其对GC的影响

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

更新 #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 应用程序中的一个事实,应用程序服务器执行足够的优化以确保这里的延迟非常小。恕我直言,与为集中访问连接对象而手工制作的类相比,适当调整的池将为您提供更好的性能。

关于java - 加载只有静态方法的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6317499/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com