标签: resource-disposal

如何强制Java线程关闭线程本地数据库连接

使用线程本地数据库连接时,线程存在时需要关闭连接.

这只能我可以覆盖调用线程的run()方法.即使这不是一个很好的解决方案,因为在退出时,我不知道该线程是否曾打开过连接.

问题实际上更为通用:如何强制线程在线程局部对象退出时调用某些终结方法.

我查看了java 1.5的源代码,发现线程本地映射设置为null,这最终会导致垃圾收集调用finalize(),但我不想指望垃圾收集器.

以下覆盖似乎是不可避免的,以确保关闭数据库连接:

@Override 
public void remove() {
    get().release(); 
    super.remove(); 
}
Run Code Online (Sandbox Code Playgroud)

其中,release()关闭数据库连接(如果已打开).但我们不知道线程是否曾使用过本地线程.如果此线程从未调用过get(),那么这里的工作就相当浪费:将调用ThreadLocal.initialValue(),在此线程上创建一个map等.

-

根据Thorbjørn的评论进一步澄清和举例:

java.lang.ThreadLocal是绑定到线程的对象的工厂类型.此类型具有对象的getter和工厂方法(通常由用户编写).当调用getter时,只有在此线程之前从未调用过它时才调用工厂方法.

使用ThreadLocal允许开发人员将资源绑定到线程,即使线程代码是由第三方编写的.

示例:假设我们有一个名为MyType的资源类型,我们希望每个线程只有一个.

在using类中定义:private static ThreadLocal resourceFactory = new ThreadLocal(){@ override protected MyType initialValue(){return new MyType(); }}

在此类的本地上下文中使用:public void someMethod(){MyType resource = resourceFactory.get(); resource.useResource(); }

get()只能在调用线程的生命周期中调用initialValue()一次.此时,MyType的实例将被实例化并绑定到此线程.此线程对get()的后续调用再次引用此对象.

经典用法示例是MyType是一些线程不安全的text/date/xml格式化程序.

但是这样的格式化程序通常不需要被释放或关闭,数据库连接也是如此,我使用java.lang.ThreadLocal来为每个线程建立一个数据库连接.

我看待它的方式,java.lang.ThreadLocal几乎是完美的.几乎是因为如果调用线程属于第三方应用程序,则无法保证资源的关闭.

我需要你的大脑绅士:通过扩展java.lang.ThreadLocal,我设法为每个线程绑定一个数据库连接,因为它的独占用途 - 包括我无法修改或覆盖的线程.我设法确保在线程因未捕获的异常而死的情况下关闭连接.

在正常线程退出的情况下,垃圾收集器关闭连接(因为MyType会覆盖finalize()).实际上它很快发生,但这并不理想. …

java thread-local resource-disposal

13
推荐指数
2
解决办法
8800
查看次数

Delphi app中的内存泄漏.如何正确处理对象和字符串?

我的问题是关于调试内存泄漏,这似乎是一场噩梦.
在我的应用程序中有一个简单的类派生自TObject.该类的所有对象都存储在派生自TObjectList以下类的类的集合/列表中:

type
  TOffer = class(TObject)
    Item: string;
    Price: string;
    Id: string;
  end;

  TOffers = class(TObjectList<TOffer>)
  protected
    procedure SetOffer(I: Integer; AOffer: TOffer);
    function GetOffer(I: Integer): TOffer;
  public
    property Offers[I: Integer]: TOffer read GetOffer write SetOffer
  end;
Run Code Online (Sandbox Code Playgroud)

使用场景:
爬虫下载商品,解析商品并保存到对象集合.这种方法似乎很方便,因为我可以稍后引用这些对象(填充网格/列表,将它们写入文件等)

问题是正确处理对象以避免内存泄漏.该应用程序在启动时分配~4Mb内存,但在处理后~12k提供它吞噬32Mb.在过程完成后由未正确处理的对象/变量引起的泄漏.

ReportMemoryLeaksOnShutdown 显示可怕的数字,但关键是 - 我不知道在哪里看,以及如何正确调试该死的东西.

另一个例子是var MyString: string需要适当处置的变量!! 这对我来说很有见地:)我认为每个过程/函数都会自动管理超出范围的变量的垃圾收集.

商品列表由函数创建:

function GetOffersList: TOffers;
begin
  Result := TOffers.Create;
  while not rs.EOF do
  begin
    Offer := TOffer.Create;
    try
       // here come collected offer attributes as variables of …
Run Code Online (Sandbox Code Playgroud)

delphi memory-leaks garbage resource-disposal

2
推荐指数
1
解决办法
2492
查看次数

C#如何追踪字体处理

我有一个正在处理的字体导致异常,我找不到字体的处理位置.我有一种感觉它被打印预览处理掉了.有人可以推荐如何追踪这个问题吗?

谢谢.

c# resource-disposal

1
推荐指数
1
解决办法
262
查看次数