精华内容
下载资源
问答
  • 文件句柄文件句柄泄漏解决

    千次阅读 2019-12-22 12:07:53
    文件句柄 在文件I/O中,要从一个文件...要从文件中读取一块数据,应用程序需要调用函数readFile,并将文件句柄内存中的地址和要拷贝的字节数传送给操作系统。当完成任务后,再通过调用系统函数来关闭该文件。 ...

    文件句柄

    在文件I/O中,要从一个文件读取数据,应用程序首先要调用操作系统函数并传送文件名,并选一个到该文件的路径来打开文件。该函数取回一个顺序号,即文件句柄(file handle),该文件句柄对于打开的文件是唯一的识别依据。要从文件中读取一块数据,应用程序需要调用函数readFile,并将文件句柄在内存中的地址和要拷贝的字节数传送给操作系统。当完成任务后,再通过调用系统函数来关闭该文件。

    文件句柄和文件描述符

    文件句柄是windows里面的叫法,文件描述符是linux里面的叫法。其实两者是同样的概念。

    最大文件句柄数

    Linux 进程最多能够打开的文件句柄数(这里的文件句柄数包括socket数,从网络读取数据也是另外一种文件读取方式)是有限制的,超过了这个限制,应用程序就会抛出异常(Too many open files.)。在Android 上,最大的数量一般都是1024,但一些定制的rom可能会有一些差别。另外,有一个概念需要先明确,文件句柄数,并不是打开的文件数。因为一个文件即使被打开,也可能没有文件描述符。

    获取文件句柄数

    那么遇到问题的时候,如何获取某个进程的文件句柄数呢?

    • 获取进程对应的ID:adb shell ps | grep '进程名'
    • 进入到对应的目录:cd /proc/进程ID/fd
    • 使用下面的命令即可能够获取到对应进程的文件句柄数:
      ls /proc/进程ID/fd -l
    • 如想要获取当前进程socket占用的文件句柄数,可以增加多个过滤:
      ls /proc/进程ID/fd -l | grep socket -c

    文件句柄泄漏定位

    通常的分析手法如下(转自:https://blog.csdn.net/xiaolli/article/details/56012228):
    (1). 确定是哪类文件打开太多,没有关闭.

    • fd leaks, 通常伴随着此进程会出现Java Exception, Native Exception 等. 在mtk 的AEE DB 中, 有一支文件 PROCESS_FILE_STATE 描述, 此进程的打开的所有文件.
      查看此文件, 确定哪个或者哪种文件打开数量最多,即追查此类文件打开如此多, 而没有被关闭的原因.

    • 如果没有DB, 当发生文件句柄泄露到1024 时, 在L 版本后, 在Kernel Log 中search “FDLEAK”, 在L 版本之前, 在Kernel Log 中search “FS_TAG”, 即可枚举出所有的此进程所打开的文件.

    • 如果问题容易复现,可以直接 adb shell ls -a -l /proc/pid/fd , 直接打印出当前此process 所有打开的文件.

    (2). 确定此类文件是在哪里打开.

    对于一些确定的文件, 比如/data/data/xxxx_app/yyyy 之类的文件, 通常开发者自己可以快速的确定打开文件的位置,基本上不需要debug,对于一些另外一些常见的场景说明如下:

    • 大批量的打开“anon_inode:[eventpoll]” 和 “pipe”, 超过100个eventpoll, 通常情况下是开启了太多的HandlerThread/Looper/MessageQueue, 线程忘记关闭, 或者looper 没有释放. 可以抓取hprof 进行快速分析. 抓取hprof 可以参考FAQ:http://online.mediatek.com/Pages/FAQ.aspx?List=SW&FAQID=FAQ08893
    • 对于system server, 如果有大批量的socket 打开, 可能是因为Input Channel 没有关闭, 此类同样抓取hprof, 查看system server 中WindowState 的情况.
    • 大批量的打开“/dev/ashmem”, 如果是Context provider, 或者其他app, 很可能是打开数据库没有关闭, 或者数据库链接频繁打开忘记关闭.

    (3). 暴力确定文件打开的位置

    • MTK 有开发了fd leaks debug 功能,可以记录每次打开fd 的backtrace, 可以参考FAQ: http://online.mediatek.com/Pages/FAQ.aspx?List=SW&FAQID=FAQ11422

    (4). 修正

    展开全文
  • 文件句柄

    千次阅读 2018-09-16 21:56:41
    1,打开文件,得到文件句柄并赋值给一个变量 2,通过句柄对文件进行操作 3,关闭文件 二.基本操作 打开模式 文件句柄 = open(‘文件路径’, ‘模式’, 指定编码) 打开文件的模式有: r ,只读模式【默认...

    python文件管理

    一.文件处理流程

    • 1,打开文件,得到文件句柄并赋值给一个变量
    • 2,通过句柄对文件进行操作
    • 3,关闭文件

    二.基本操作

    1. 打开模式
      文件句柄 = open(‘文件路径’, ‘模式’, 指定编码)
      打开文件的模式有:
      r ,只读模式【默认模式,文件必须存在,不存在则报错】
      w,只写模式【不可读;不存在则创建;存在则清空内容】
      x, 只写模式【不可读;不存在则创建,存在则报错】
      a, 追加模式【可读;不存在则创建;存在则只追加内容】
      “+” 表示可以同时读写某个文件
      r+, 读写【可读,可写】
      w+,写读【可读,可写】
      x+ ,写读【可读,可写】
      a+, 写读【可读,可写】
      “b”表示以字节的方式操作
      rb 或 r+b
      wb 或 w+b
      xb 或 w+b
      ab 或 a+b
      注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码
    2. 操作
      (1)读
    f.read() #按字符读文件
    f.readline() #按行读文件
    f.readlines() #按行读所有文件内容

    (2)写

    f.write() #在当前光标后开始写文件 

    (3)刷到硬盘

    f.flush() #立即刷到硬盘

    (4)关闭文件

    f.close() #关闭文件

    (5)光标移动

    f.read() #按字符读取问价,光标按字符移动
    f.seek() #按字节读取文件,光标按字节移动;
    f.seek( ,whence) #whence默认为0,代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。
    f.truncate() #默认从当前光标位置截断,后面内容删除,可传入参数,指该字节处截断
    f.tell() #获取文件当前位置

    (6)上下文管理

    with open(‘文件路径’, ‘模式’) as f: #执行完操作后自动删除f
        pass         

    (7)扩展
    复制图片(视频)文件:

    read_file = open(‘a.jpg’,’rb’)
    write_file = open(‘a.copy.jpg’ , ‘wb’)
    write_file.write(read_file.read())
    read_file.close()
    write_file.close()

    文件修改:

    import os
    os.remove(‘a.txt’)             #删除a.txt文件
    os.rename(‘.a.txt.swp’, ‘a.txt’)    #重命名.a.txt.swp文件为a.txt

    linux中文件句柄泄露

    1.文件句柄泄露

    • 在linux中,如果一个文件正在被某个进程占用,用户操作rm删除该文件后,我们ls后发现文件已经不存在了,但实际上该文件仍然在磁盘上。直到使用它的进程退出后,文件占用的磁盘空间才会被释放。

    • 其原理如下:

      • 在linux中,每个文件都有2个计数器,i_count和i_nlink。i_count表示文件正在被调用的数量。i_nlink表示硬链接的数量。可以理解为i_count为内存的引用计数器,i_nlink为磁盘的引用计数器。当一个文件被某一个进程引用时,对应i_count数就会增加;当创建文件的硬链接的时候,对应i_nlink数就会增加。
      • rm操作是将文件的i_nlink减少了,如果没有其它的硬链接i_nlink就为0了;但由于该文件依然被进程引用,因此,此时文件对应的i_count并不为0,所以即使执行rm操作,但系统并没有真正删除这个文件,当只有i_nlink及i_count都为0的时候,这个文件才会真正被删除。也就是说,还需要解除该进程的对该文件的调用才行。

    备注,在这种情况下,就需要使用lsof工具来查看文件被进程的占用情况了。

    解决进程文件句柄泄露导致磁盘空间无法释放问题

    问题的产生

    • 突然接到一台服务器磁盘空间使用率达到90%的报警,于是登陆机器查看磁盘使用情况,发现确实外挂到/data的一块磁盘使用率达到了90%:
    [root@awsuw7-46 data]# df -h
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/xvda2      100G   17G   84G  17% /
    devtmpfs         30G     0   30G   0% /dev
    tmpfs            29G     0   29G   0% /dev/shm
    tmpfs            29G  2.7G   27G  10% /run
    tmpfs            29G     0   29G   0% /sys/fs/cgroup
    /dev/xvdf       246G  209G   26G  90% /data
    tmpfs           5.8G     0  5.8G   0% /run/user/1000
    tmpfs           5.8G     0  5.8G   0% /run/user/1003

    分析问题

    • 对于这种情况我一般的处理方法是跳到对应的目录,查看哪个目录占用的空间比较大,然后进一步清理。由于这块磁盘是外挂到/data目录,因此查看下该目录下各个目录磁盘的占用情况:
    [root@awsuw7-46 data]# du -h --max-depth=1
    3.7G    ./photo
    16K ./lost+found
    9.1G    ./mls2
    36K ./parser
    79G ./web
    15G ./mls
    106G   
    • 可以发现一个奇怪的现象:该外挂目录总共才使用了106G,但是df -h显示的是该磁盘已经使用了209G,那么使用的另外那103G去哪儿了呢,况且这块磁盘也没有多个分区,就这一个分区且挂载到了/data下。这确实是个很奇怪的问题,于是网上搜索了下原因,原来是不正确的删除文件导致的:
      • 在Linux操作系统中,当一个文件被删除后,在文件系统目录中已经不可见了,所以du就不会再统计它了。然而如果此时还有运行的进程持有这个已经被删除了的文件的句柄,那么这个文件就不会真正在磁盘中被删除, 分区超级块中的信息也就不会更改,所以df命令查看的磁盘占用没有减少。我们知道在Linux中磁盘分区的超级块是非常重要的,在superblock中记录该分区上文件系统的整体信息,包括inode和block的总量,剩余量,使用量,以及文件系统的格式等信息。因此,superblock不更新,那么磁盘的使用量必然不会变化,操作系统对于文件的存盘都是需要事先读取superblock的信息,然后分配可用的inode和block。

    解决问题

    • 1.首先找出文件句柄泄露的进程,我的方法比较low,找出系统中启动时间比较久的java进程(因为这台机器主要是java服务),然后用lsof看这个进程的文件句柄使用情况。之所以这么做主要是因为最近启动的进程发生句柄泄露的可能性很小,因为即使存在句柄泄露,重启后也会释放文件句柄的。可以看出2962这个进程最可能发生句柄泄露了。
    [root@awsuw7-46 data]# ps -eo pid,lstart,comm | grep java
      746 Thu Jan 18 19:44:15 2018 java
     1117 Thu Feb  8 02:20:03 2018 java
     1160 Thu Feb  8 02:20:09 2018 java
     2962 Thu Nov 16 23:08:40 2017 java
     3610 Wed Feb  7 22:55:37 2018 java
     4579 Thu Feb  8 20:45:09 2018 java
     5155 Mon Dec 25 19:01:32 2017 java
     6481 Wed Jan 10 05:16:28 2018 java
     6519 Thu Jan 18 00:51:07 2018 java
     9756 Thu Feb  8 02:36:23 2018 java
    • 2.使用lsof分析上面找到的进程文件句柄使用情况,可以看出该进程确实存在句柄泄露,而且非常严重,已经有2208个文件没有释放了:
    [root@awsuw7-46 ~]# lsof -p 2962 | grep "delete" | wc -l
    2208
    [root@awsuw7-46 ~]# lsof -p 2962 | grep "delete" | head -n 20
    java    2962  web   17r      REG              202,2     2098273   17844538 /tmp/winstone962950350375526798.jar (deleted)
    java    2962  web  168w      REG             202,80           0    1969499 /data/web/mls/data/jobs/mls_91/builds/590/23.log (deleted)
    java    2962  web  325w      REG             202,80           0    6455947 /data/web/mls/data/jobs/mls_39/builds/1080/10.log (deleted)
    java    2962  web  341w      REG             202,80           0    1975873 /data/web/mls/data/jobs/mls_113/builds/1054/29.log (deleted)
    java    2962  web  347w      REG             202,80           0    2506849 /data/web/mls/data/jobs/mls_59/builds/.1073/21.log (deleted)
    java    2962  web  350w      REG             202,80        8192    1975877 /data/web/mls/data/jobs/mls_113/builds/1054/31.log (deleted)
    java    2962  web  352w      REG             202,80           0    5387403 /data/web/mls/data/jobs/mls_80/builds/505/23.log (deleted)
    java    2962  web  354w      REG             202,80           0    3422611 /data/web/mls/data/jobs/mls_29/builds/.385/23.log (deleted)
    • 3.重启上面找到的发生内存泄露的进程,发现磁盘使用量回归正常状态:
    [ec2-user@awsuw7-46 ~]$ df -h
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/xvda2      100G   17G   84G  17% /
    devtmpfs         30G     0   30G   0% /dev
    tmpfs            29G     0   29G   0% /dev/shm
    tmpfs            29G  2.7G   27G  10% /run
    tmpfs            29G     0   29G   0% /sys/fs/cgroup
    /dev/xvdf       246G  128G  106G  55% /data
    tmpfs           5.8G     0  5.8G   0% /run/user/1000
    tmpfs           5.8G     0  5.8G   0% /run/user/1003
    tmpfs           5.8G     0  5.8G   0% /run/user/1005
    tmpfs           5.8G     0  5.8G   0% /run/user/1008
    tmpfs           5.8G     0  5.8G   0% /run/user/1007
    tmpfs           5.8G     0  5.8G   0% /run/user/1006
    展开全文
  • 文件句柄与文件描述符 文章,解释为什么lsof和proc/sys/fs/file-nr有数量级差异: https://mp.weixin.qq.com/s/3B1Or4Y-rTRZ0_0shPxhBQ file-nr文件里面的第一个字段代表的是内核分配的struct file的个数,也就是...

    文件句柄与文件描述符

    文章,解释为什么lsof和proc/sys/fs/file-nr有数量级差异:
    https://mp.weixin.qq.com/s/3B1Or4Y-rTRZ0_0shPxhBQ
    file-nr文件里面的第一个字段代表的是内核分配的struct file的个数,也就是文件句柄个数,而不是文件描述符。
    lsof显示对是文件描述符。
    ![

    名词解释

    文件描述符(file descriptor):
    内核(kernel)利用文件描述符(file descriptor)来访问文件。 文件描述符是非负整数。 打开现存文件或新建文件时,内核会返回一个文件描述符。 读写文件也需要使用文件描述符来指定待读写的文件。
    文件句柄(file handle):
    在文件I/O中,要从一个文件读取数据,应用程序首先要调用操作系统函数并传送文件名,并选一个到该文件的路径来打开文件。该函数取回一个顺序号,即文件句柄(file handle),该文件句柄对于打开的文件是唯一的识别依据。要从文件中读取一块数据,应用程序需要调用函数ReadFile,并将文件句柄在内存中的地址和要拷贝的字节数传送给操作系统。当完成任务后,再通过调用系统函数来关闭该文件。

    可以看作文件描述符指向具体文件句柄,文件句柄指向要操作对文件。

    展开全文
  • 下面的问题和本文很可能是一个意思...有的C语言API只接受文件句柄作为参数。这时我们要处理的数据又已经在内存中了。那么怎样用文件句柄来操作这块数据呢? 比如zlib 中的 gzip File Access Functions 。 ZEXTERN g
    下面的问题和本文很可能是一个意思:
    
    • How to read memory using file handler?
    • How to read string as file?

    有的C语言API只接受文件句柄作为参数。这时我们要处理的数据又已经在内存中了。那么怎样用文件句柄来操作这块数据呢?

    比如zlib 中的 gzip File Access Functions

    ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
    
    ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
    

    它只有两种形式,或者直接打开一个文件,或者打开一个文件描述符。这时如果想处理已经存在于内存中的数据,就需要些别的处理方式了。

    借助临时文件

      FILE * tFile = tmpfile ();
      fwrite(bytes, 1 , length , tFile);
      fseek(tFile , 0 , SEEK_SET );
      
      gzFile gzfile = gzdopen(fileno(tFile),"rb");    
      // gzip related operation
      gzclose(tFile);        
    

    借助libc的函数

    The GNU C Library 中的 String Streams 提供了下面两个函数:

    FILE * fmemopen (void *buf, size_t size, const char *opentype);
    
    FILE * open_memstream (char **ptr, size_t *sizeloc);
    

    展开全文
  • NSURLSession发请求下载文件(代理) 解决内存飙升问题 实现下载的断点续传
  • Windows句柄有点象C语言中的文件句柄。 如果想更透彻一点地认识句柄,我可以告诉大家,句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果...
  • 文件句柄NSFileHandle

    2017-12-12 12:22:46
    在这种情况下我们可以使用文件句柄(NSFileHandle).来解决这个问题. 在苹果官方文档里面最重要的一句话就是: When using a file handle object to communicate asynchronously with a socket, you must i
  • 文件句柄和文件描述符 在我们跨平台开发的时候,经常会碰到这俩个概念 文件描述符: 本质上是一个索引号(非负整数),系统用户层可以根据它找到系统内核层的文件数据。这是一个POSIX标准下的概念,常见于Linux系统...
  • 句柄不是指针,操作系统用句柄可以找到一块内存,这个句柄可能是标识符,map的key,也可能是指针,看操作系统怎么处理的了。fd算是在某种程度上替代句柄吧;Linux 有相应机制,但没有统一的句柄类型,各种类型的...
  • 在我们日常编程中经常会遇到文件描述符(file descriptor)和文件句柄(file handler)这两个概念,特别是需要开发跨平台(跨windows和linux)项目的时候会被这两个概念搞得很头痛,所以下面来说说它们是什么东西及...
  • 文件描述符 VS 文件句柄

    千次阅读 2015-01-26 09:56:20
    文件描述符 VS 文件句柄 文件描述符是标准 C 里用的,是 int 型的,比如调用 open 函数成功后会返回一个与当前文件相关联的 int 型数字。     文件句柄是 Windows 里用的,是 HANDLE 型的,比如创建文件 ...
  • 文件句柄_文件描述符

    2020-05-06 21:14:25
    文件句柄 : FILE * ,是个指针; 文件描述符: _IO_FILE结构体中的 “int _fileno” 是个 int 值
  • 句柄

    千次阅读 多人点赞 2019-11-26 18:48:45
    句柄主要用来标识应用程序中的一个对象,如窗口、实例、菜单、内存、输出设备、控制或文件等。 例如在模块文件定义文件中,菜单资源中的菜单项被定义并且赋给了一个句柄值。应用程序的菜单栏中,第一个菜单的第一个...
  • 1、文件句柄 文件句柄就是一个文件索引。 当用户发起一个请求,就会产生一个文件句柄文件句柄会随着请求的增加而增多,系统对文件句柄是有限制的,默认的操作系统设置1024个句柄。 2、文件句柄设置方式 ...
  • 句柄作用

    千次阅读 2014-10-27 17:05:24
    >(Microsoft Press,by Richard Wilton)一书中句柄的概念是这样的:在Windows环境中,句柄是用来标识项目的,这些项目包括:模块(module)、任务(task)、实例(instance)、文件(file)、内存块(block of memory)、...
  • 去掉内存文件句柄限制 以coherence用户为例子: 修改:/etc/security/limits.conf   coherence hard nproc 655360 coherence soft nproc 655360   coherence hard nofile 65536 coherence soft no...
  • 句柄文件描述符

    2019-05-16 10:33:59
    文件句柄和文件描述符类似,它也是一个非负整数,也用于定位文件数据在内存中的位置。 由于linux下所有东西都被看成是文件,比如文件(也许叫文档比较合适一点)、目录、进程、网络socket、各种硬件设备等,所以...
  • 1.打开/etc/security/limits.conf,里面有很详细的注释,找到如下设置(如果没有就插入) * soft nofile 51200 * hard nofile ...设置虚拟内存: ulimit -v unlimited 关闭旧的session,重连一个 session,验证 ulimit -a
  • 程序里主线程进行界面的维护,工作者线程后台进行串口的通讯,每次通讯历时700ms,主程序关闭时经常会提示68K内存泄漏或者句柄泄漏,一查,原因在于主程序关闭资源释放之后,线程仍在工作。主要参考这篇文章。 解决...
  • Linux系统默认的最大文件句柄数(打开文件数,Linux下一切皆文件,这里仅做类比句柄描述),系统默认是1024。用ulimit -n进行查看。当存在句柄泄露没有释放时,系统会报错:Too many open files。   查看进程打开...
  • 句柄详解,什么是句柄句柄有什么用?

    万次阅读 多人点赞 2018-10-25 19:44:23
    最近在做项目时遇到了句柄的概念,之前只...1.这里将句柄所能标识的所有东西(如窗口、文件、画笔等)统称为“对象”。 2.图中一个小横框表示一定大小的内存区域,并不代表一个字节,如标有0X00000AC6的横框表示4...
  • Linux文件句柄泄漏

    2020-09-11 20:49:17
    用户程序如果不及时释放无用的句柄,将会引起句柄泄露,从而可能造成申请资源失败,导致系统文件句柄用光连接不能建立。本文主要介绍Linux下如何查看和修改进程打开的文件句柄数,避免这类问题的发生。 句柄介绍 ...
  • 文件句柄备忘

    2013-03-22 15:19:30
    句柄不是指针,但利用句柄能够得到一段内存地址, 句柄的设计目标是防止用户随意修改内核中文件,因此用户模式下的程序永远不可能获得一个内核对象的实际地址(一般情况下)。 那么Handle的意义何在? 它实际上是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 136,971
精华内容 54,788
关键字:

内存句柄文件句柄的作用