6

十分に理解されている特定の状況では、アプリケーションはあまりにも多くのソケット (データベース接続) を開き、OS が許可する最大オープン ファイルに達します。私たちはこれを理解しています。問題を修正し、制限を引き上げています。

説明できないのは、接続数が減り、制限内に収まった後でも、アプリケーションの一部が回復しない理由です。

この場合は、Tomcat で実行されるアプリケーションです。

これが発生すると、最初に「開いているファイルが多すぎます」というエラーが表示され始めます。

SEVERE: Socket accept failed
java.net.SocketException: Too many open files
        at java.net.PlainSocketImpl.socketAccept(Native Method)
        at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390)
        at java.net.ServerSocket.implAccept(ServerSocket.java:453)
        at java.net.ServerSocket.accept(ServerSocket.java:421)
        at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:61)
        at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:310)
        at java.lang.Thread.run(Thread.java:619)

最終的に、NoClassDefFoundErrorHTTP 接続を開こうとしているアプリケーション スレッド内に s が表示されるようになります。

java.lang.NoClassDefFoundError: org/apache/commons/httpclient/protocol/ControllerThreadSocketFactory
        at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:128)
        at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
        at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1349)
       [...]
Caused by: java.lang.ClassNotFoundException: org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
        ... 8 more

誤った接続がなくなると、サーバーは再び接続の受け入れを開始し、すべて問題ないように見えますが、後者のエラーが常に stderr に吐き出されたままになります。

アプリケーションは通常、アンロードされたクラスを stdout に記録しますが、「開いているファイルが多すぎます」エラーの直前、最中、または直後に、そのようなログは表示されません。

私の最初の理論は、Hotspot JVM は「開いているファイルが多すぎます」と遭遇すると、未使用に見えるクラスをアンロードするというものでした。

編集: Stephen Cが以下に示すように、クラスをアンロードしていて、最初のリロード時にエラーが発生した場合、それが回復しない理由を説明できます. それは良い作業理論だと思います。Sun のドキュメントに記載されていますか? 通常のクラスのアンロードとは異なり、クラスがアンロードされていることをログに記録しないのはなぜですか?

プラットフォームの詳細:

Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)

Apache Tomcat Version 6.0.18
4

2 に答える 2

2

ClassNotFoundExceptionsが繰り返される理由は、ソケットリークの問題が原因でControllerThreadSocketFactoryの最初に試行されたクラスの初期化が失敗したためだと思います。これで、コードはクラスのクラス初期化を再トリガーすることを繰り返し実行し、元の問題を報告しています。

クラスの初期化が最初に失敗した場合は、それだけです。JVMはそれを再試行しません。

于 2010-03-21T01:56:39.270 に答える
0

Weblogic 8.1 / JRockIt R27.2と、リソースバンドルをロードしようとして、開いているファイルの数の制限が原因で失敗する一連のWebアプリケーションを使用して同じ問題に直面しています。アプリケーションを停止および開始する(つまり、クラスローダーのアンロードとロード)と、処理が再開されます。

于 2010-04-13T20:17:40.577 に答える