「Java.net.SocketException:Too many open files」に達するまで数時間(Ubuntu 10.04で)正常に動作するJavaアプリがあります。Sender.Javaのコードは見つかった ここ
スレッドごとにHttpPut
とHttpPost
の新しいインスタンスを作成したからですか? Apache-commons HTTPClient 4を使用しています。
例外ログは次のとおりです。
Java.net.SocketException: Too many open files
at Java.net.Socket.createImpl(Socket.Java:414)
at Java.net.Socket.connect(Socket.Java:544)
at org.Apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.Java:123)
at org.Apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.Java:133)
at org.Apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.Java:149)
at org.Apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.Java:108)
at org.Apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.Java:415)
at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:641)
at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:576)
at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:554)
at com.marketplace.io.Sender.doBasicHttpPost(Sender.Java:434)
at com.marketplace.io.Sender.appVisualExists(Sender.Java:223)
at com.marketplace.io.Sender.addVisualToCollection(Sender.Java:350)
at com.marketplace.service.ImageThread.run(ImageThread.Java:136)
at Java.util.concurrent.Executors$RunnableAdapter.call(Executors.Java:471)
at Java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.Java:334)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:166)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1110)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:603)
at Java.lang.Thread.run(Thread.Java:636)
438行目で、応答をストリームとして取得し、それをバイト配列に変換します。 entity.getContent()によって返されるInputStreamは閉じられません。これが問題の原因である可能性があります。また、 HttpEntity.consumeContent() は、関連する理由により非推奨になりました。
「Java.net.SocketException:Too many files open」は、Javaサーバーアプリケーション(Tomcat、Weblogic、WebSphereなど、クライアントが頻繁に接続および切断する場合)で表示されます。
ソケット接続はファイルのように扱われ、制限されたリソースであるファイル記述子を使用します
オペレーティングシステムごとに、管理できるファイルハンドルの数に制限があります。
要するに、クライアントが頻繁に接続および切断するため、このエラーが発生します。あなたの側でそれを処理したい場合、2つのオプションがあります:
1)プロセスごとに開いているファイルハンドルまたはファイル記述子の数を増やします。
UNIXベースのオペレーティングシステム(例: UbuntuまたはSolarisでは、コマンドlimit -aを使用して、プロセスごとに許可されるオープンファイルハンドルの数を確認できます。
$ ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
open files (-n) 256
pipe size (512 bytes, -p) 10
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 2048
virtual memory (kbytes, -v) unlimited
開いているファイル(-n)256は、プロセスごとに256の開いているファイルハンドルのみが許可されていることを確認できます。 Javaプログラム、Tomcat、weblogic、またはその他のアプリケーションサーバーがJavaプログラムであり、JVMで実行され、この制限を超える場合、Javaがスローされます。 net.SocketException:開いているファイルが多すぎますエラー。
Ulimit -nを使用して、この制限を変更できます。 4096ですが、UNIXシステム管理者の助言を受けて行ってください。別のUNIXサポートチームがある場合は、それらにエスカレートすることをお勧めします。
2)オペレーティングシステムのTIME_WAIT状態のタイムアウトを減らします
UNIXベースのシステムでは、現在の構成を/ proc/sys/net/ipv4/tcp_fin_timeoutファイルで確認できます。
Windowsベースのシステムでは、Windowsレジストリでこの情報を確認できます。以下の手順に従って、WindowsのTCPTIME_WAITタイムアウトを変更できます。
1) Open Windows Registry Editor, by typing regedit in run command window
2) Find the key HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\tcpip\Parameters
3) Add a new key value pair TcpTimedWaitDelay asa decimal and set the desired timeout in seconds (60-240)
4) Restart your windows machine.
また、Linuxの最大オープンファイル制限を確認することもできます。この 関連リンク は、特注のJavaベースの製品用ですが、問題を修正するために必要な手順をうまく説明しています。
(解決済み)
データベースサーバーのvar/logがいっぱいであるため、最近同じエラーが発生しました。
#df -h
S.ficheros Size Used Avail Use% Montado en
/dev/cciss/c0d0p3 126G 126G 0G 100% /var
#echo "">/var/log/postgresql/postgresql.log
これでエラーはなくなりました!!!
重要:postgresql.logにログインする内容を確認し、postgresql.confを確認します
さようなら
@_ jpgo
Finallyブロックで接続を閉じることで問題を解決します。
public static String postMethod(String jsonStr,String sendUrl){
String resultJson = "";
HttpClient httpClient = new HttpClient();
PostMethod post = new PostMethod(sendUrl);
post.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");
NameValuePair[] param = { new NameValuePair("message",jsonStr)} ;
post.setRequestBody(param);
try {
httpClient.executeMethod(post);
resultJson = post.getResponseBodyAsString();
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
post.releaseConnection();
((SimpleHttpConnectionManager)httpClient.getHttpConnectionManager()).shutdown();
}
return resultJson;
}