too many open files
(备注:本文最早写于2016年,发表在网易博客,因网易博客停止运营,将文章转移到云栖社区。
当时因工作的原因用英文书写,表达的不准确的地方望留言指正)
Recently, I looked into the “too many open files” issues on linux server. I summarized the analysis in detail. If you encounter the file descriptor leaks problem, or are interested in this kind of issue,it might be helpful to you.
What’s file descriptor?
On linux server, opening a file or a network connection would cost a file descriptor. A application has limitation on file descriptors, each process can cost at most 1024 file descriptors by default.
However, we can enlarge the value, but in most cases, we don’t need to enlarge the value. And enlarging the value wouldn’t give us much help if there are file descriptor leaks in our code.
How to find out file descriptor leaks?
When our applications cost file descriptors more than the limitation(default 1024),we will encounter the too many open files exception on linux.
As far as I know, there are at least 3 kinds of Exceptions which could be caused by too many open file:FileNotFoundException,ClassNotFoundException,UnknownHostException.
File descriptor leaks happened when we didn’t close Stream ( like IO Streams or Network Connections or DB Connections ) after we finished use it. The object out of reference should not imply that the resource has been released .
We can use the lsof command to show all the file descriptors which are opened by our application.
If there are many connections keeps CLOSE_WAIT or can’t identify protocol for long time (may be some minutes), or the file opening number keeps going up, the file descriptor leaks might happened.
Release file descriptor
It is always a good manner to release the resources using try…catch…finally blocks.
Release File Stream
For IO Streams on local file, the file descriptor could be immediately released after we close the stream. If we don’t close it in the code, it would be released after GC, which could takes much longer time.
Release Network Stream
For Network Connections, it is a litter complex. For any TCP based protocol, It needs four-way handshake to release the connections.
For more detail, we can refer to http://en.wikipedia.org/wiki/Transmission_Control_Protocol
Take Http Connections in Java for example. We use the HttpURLConnection as the Client to connect the Servlet deployed in tomcat server.
Passive Close
If we don’t close the connection actively. The connection status would keep ESTABLISHED until the Initiator close it, meaning send FIN.
How long will it keep ESTABLISHED? It depends on the keep-alive timeoutconfiguration on server. For details on HTTP keep-alive,
we can refer to http://docs.oracle.com/javase/7/docs/technotes/guides/net/http-keepalive.html
After the server close the connection, the connection STATUS on our side would change to CLOSE_WAIT. This status implies that the server is waiting for the client to close the connection, meaning send ACK and FIN.
If we close the connection now, the connection would be release on our side. And the connection on the server side would change to TIME_WAIT, which needs 2MSL to release the connection.
For more detail on 2MSL, we can refer to http://www.vorlesungen.uni-osnabrueck.de/informatik/networking-programming/notes/22Nov96/5.html .
If we don’t ,the file descriptor leaks might happen. The connection which is in CLOSE_WAIT can only be released by 3 ways:
1、 GC
2、 after (net.ipv4.tcp_fin_timeout+2MSL) configured in the other site server. Usually >5 minutes.
3、 After more than net.ipv4.tcp_keepalive_time (default 2 hours) configured in the other site server.
The CLOSE_WAIT connections may change into can’t identify protocol before we close it.
Active Close
If we actively close the connection, meaning we close the connection before the other side server close it. The connection would change into TIME_WAIT before released.
Then it will wait 2MSL to release the connection.
The TIME_WAIT connections are out of application’s control, and it wouldn’t be count in application’s file descriptor.
We usually close http connection like this:
It works fine for most cases.
But in the following case it can’t close the connection as we want.
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpConnectionTest {
public static void main(String[] args) throws Exception {
String urlString = "http://www.jupiteronline.com/~/media/Literature/Factsheets/SICAV/Jupiter%20USD%20Dynamic%20Bond%20Factsheet.pdf";
InputStream in = null;
try{
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
in = conn.getInputStream();
}catch(Exception e){
e.printStackTrace();
}finally{
if(null!=in){
in.close();
}
}
}
}
In this case, An exception throw when we try to get the InputStream, since in==null, but the connection has been established.
In order to guarantee the connection would be closed, we change it to this way.
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpConnectionTest {
public static void main(String[] args) throws Exception {
String urlString = "http://www.jupiteronline.com/~/media/Literature/Factsheets/SICAV/Jupiter%20USD%20Dynamic%20Bond%20Factsheet.pdf";
InputStream in = null;
HttpURLConnection conn =null;
try{
URL url = new URL(urlString);
conn = (HttpURLConnection) url.openConnection();
in = conn.getInputStream();
}catch(Exception e){
e.printStackTrace();
}finally{
if(null!=in){
in.close();
}
if(null!=conn){
InputStream es = conn.getErrorStream();
if(null!=es){
es.close();
}
}
}
}
}
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
阿里云机器学习平台PAI使用简明教程
概述 阿里云机器学习平台是构建在阿里云MaxCompute(原ODPS)计算平台之上,集数据处理、建模、离线预测、在线预测为一体的机器学习平台。很多用户在初次使用PAI过程中因为对平台比较陌生,总是会遇到这样或那样的困惑。本文以通用的机器学习流程为指导,结合PAI平台逐一介绍数据准备、模型搭建与训练、模型部署与调用,将目前PAI平台的主要操作流程做一个梳理。 本文的主要目的是做PAI平台使用流程的演示,所以算法上选择最简单的线性回归算法,便于用户的理解和操作。 操作 数据准备 1、DataStudio中创建数据表 SQL脚本 CREATE TABLE `lm_test_input` ( `value` bigint, `output1` bigint ) ; 2、数据导入 目前支持多种方式将数据导入到表,如果是大数据量导入,请使用t
- 下一篇
【直播预告】:Java Spring Boot实战系列课程(第十讲):Spring Boot 2.0实战高并发分布式缓存
内容概要:Redis作为开源分布式高并发缓存,在互联网公司高并发系统中广泛使 用,本次课程讲解如何使用最新的Java Spring Data实战Redis,以及底层API的实现源码。主讲人:徐雷(阿里云栖特邀Java专家)直播时间:2019年1月1日 周二 今晚20:00直播地点:【阿里Java技术进阶】钉钉群详情请看下方图片: 想看免费直播的提前扫码入群,前九讲均在群中有回放视频
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Linux系统CentOS6、CentOS7手动修改IP地址
- 2048小游戏-低调大师作品
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16