顯示具有 鳥事 標籤的文章。 顯示所有文章
顯示具有 鳥事 標籤的文章。 顯示所有文章

2012年7月27日 星期五

fwrite 2GB file size limitation in Linux

Today our system popped a error message , about file size exceed limitation, and something wrong with login process. I just think about some software could store their data/logs over 2GB. Then "google" tell me why !!

[Question]

#include

int main(void) {
    char c[] = "abcdefghij";
    size_t rez;
    FILE *f = fopen("filldisk.dat", "wb");
    while (1) {
        rez = fwrite(c, 1, sizeof(c), f);
        if (!rez) break;
    }
    fclose(f);
    return 0;
}

When I run the program (in Linux), it stops when the file reaches 2GB

[Answers]

This is due to the libc (the standard C library), which by default on a x86 (IA-32) Linux system is 32-bit functions provided by glibc (GNU's C Library). So by default the file stream size is based upon 32-bits -- 2^(32-1).


[Solutions]
#define _FILE_OFFSET_BITS 64

#include
int main(void) {
    char c[] = "abcdefghij";
    size_t rez;
    FILE *f = fopen("filldisk.dat", "wb");
    while (1) {
        rez = fwrite(c, 1, sizeof(c), f);
        if ( rez < sizeof(c) ) {
            break;
        }
    }
    fclose(f);
    return 0;
}

Note: Most systems expect fopen (and off_t) to be based on 2^31 file size limit. Replacing them with off64_t and fopen64 makes this explicit, and depending on usage might be best way to go.


reference: http://stackoverflow.com/questions/730709/2gb-limit-on-file-size-when-using-fwrite-in-c
      http://www.suse.de/~aj/linux_lfs.html

2010年11月11日 星期四

free -- cached and buffers(2)

一般程式在執行,與進入CPU大致上會有幾個資料搬移的作業

Disk(code) <--> RAM <--> L2 Cache <--> L1 Cache(inside CPU)

當程式要執行時會愈往右邊走,執行完畢時,會慢慢走回左邊,如果都用不到,始終回到只剩DISK

以上的Cache跟主題要講的Cached有些類似,但不是指同一件事

一支程式要執行時,會有需要將使用的資料從File(Disk)讀起來使用的時候

讀起來就會進入RAM,但結束時理當要釋放這個RAM給其他程式使用

Linux考量到其他的程式可能也會用到,所以會先Cache住,如果有要用到,可以馬上反應使用

這是指在DRAM充裕的狀況下,如此運作對效能有幫助

但如果因為導致實體記憶體被吃光,而使用到Swap空間時,就輪到CPU倒楣

使用上應特別注意

其中的 Cached Memory 會依據系統的使用狀況做動態調整,借此以提高系統效能. /proc/sys/vm/drop_caches 的預設值為 0,也就是啟動 cache 的功能.如果你不喜歡這些功能或者覺得它不夠Smart的話,可以把他取消掉.在 Kernel 2.6.16 之後的本版可以透過 /proc/sys/vm/drop_caches 來釋放 Cached Memory

釋放 pagecache 所使用的 Cached Memory.



[root@localhost]# echo 1 > /proc/sys/vm/drop_caches

釋放 dentries,inodes 所使用的 Cached Memory.





[root@localhost]# echo 2 > /proc/sys/vm/drop_caches

釋放 pagecache,dentry,inode 所使用的 Cached Memory.





[root@localhost]# echo 3 > /proc/sys/vm/drop_caches




free


total used free shared buffers cached

Mem: 1023916 975816 48100 0 26376 465844

-/+ buffers/cache: 483596 540320

Swap: 2096440 105564 1990876


計算方式


total used free shared buffers cached

Mem: a b c d e f

-/+ buffers/cache: g h

Swap: i j ka = 總記憶體大小

b = 配給 buffers 與 cache 的記憶體大小(包含未用的 buffers 與 cache)

c = 剩下的記憶體大小

e = 配給 buffers 但未用的記憶體大小

f = 配給 cache 但未用的記憶體大小

g = buffers 與 cache 被使用掉的記憶體大小,也就是實際被應用程式用走的

h = 那這個就是實際剩下的記憶體大小


a = b + c

a = g + h

g = b - e - f

h = c + e + f


buffer 與 cache 的區別:

A buffer is something that has yet to be "written" to disk.

A cache is something that has been "read" from the disk and stored for later use.




一般情況下,Linux kernel 會盡可能多地利用 RAM 的空閑空間作為 cache/buffer 以最大幅度地提高系統性能。當系統中運行的應用程序占用的 RAM 增加時,則將 cache/buffer 所占用的空間釋放出來,讓渡給應用程序使用。


Mem: 那一行顯示了實際記憶體的使用率;

Swap: 顯示的是系統 swap 空間的使用率;

-/+ buffers/cache: 則是目前撥給系統緩衝區的實體記憶體數量。



記憶體管理的概觀

當系統開機一段時間後,像是「top」這種傳統的 Unix 工具常常回報少的可憐的可用記憶體數值,在我寫這篇文章的系統中,就算我總共有 512 MB 的記憶體在我的系統裡,但約開機m後三個小時,我只剩下 60 MB 的可用記憶體,那些記憶體到底跑到那裡去了?


用掉最多記憶體的地方是磁碟快取 (disk cache),目前它總共用了超過 290 MB 的記憶 (在 top 裡的「cached」項目中),快取記憶體 (cached memory) 基本上是空閒的,當有新/執行中的程式需要記憶體的話,它會快速的被取回來。


為什麼 Linux 使用這麼多的記憶體來當作磁碟快取 (disk cache) 呢?主要的原因便是:假如 RAM 沒有被使用的話,它便是閒放在那邊浪費著不用。如果把資料放在用 RAM 組成的磁碟上,它的存取速度比直接從硬碟上存取還要快上 1000 倍。假如在快取裡找不到該資料,當然還是得直接從磁碟裡存取,但就如同上面說的,您將可以節省些微的存取時間。



Out of Memory

more /var/log/messages


kernel: Mem-info:

kernel: Zone:DMA freepages: 2916 min: 0 low: 0 high: 0

kernel: Zone:Normal freepages: 758 min: 766 low: 4031 high: 5791

kernel: Zone:HighMem freepages: 125 min: 253 low: 506 high: 759

kernel: Free pages: 3799 ( 125 HighMem)

kernel: ( Active: 237940/1195, inactive_laundry: 1, inactive_clean: 0, free: 3799 )

kernel: aa:0 ac:0 id:0 il:0 ic:0 fr:2916

kernel: aa:209592 ac:2087 id:1190 il:1 ic:0 fr:758

kernel: aa:26033 ac:232 id:0 il:0 ic:0 fr:125

kernel: 0*4kB 2*8kB 4*16kB 2*32kB 4*64kB 2*128kB 1*256kB 1*512kB 0*1024kB 1*2048kB 2*4096kB = 11664kB)

kernel: 8*4kB 1*8kB 175*16kB 6*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3032kB)

kernel: 1*4kB 0*8kB 1*16kB 1*32kB 1*64kB 1*128kB 1*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 500kB)

kernel: Swap cache: add 5156731, delete 5156620, find 19439534/21006374, race 0+19

kernel: 4115 pages of slabcache

kernel: 1566 pages of kernel stacks

kernel: 13 lowmem pagetables, 5378 highmem pagetables

kernel: 32 bounce buffer pages, 32 are on the emergency list

kernel: Free swap: 0kB

kernel: 261760 pages of RAM

kernel: 32384 pages of HIGHMEM

kernel: 5781 reserved pages

kernel: 14591 pages shared

kernel: 116 pages swap cached

kernel: Out of Memory: Killed process 25580 (java).

free -- cached and buffers(1)

以下參考自:http://egloo.wordpress.com/2008/10/29/linux-cached-memory/
In Linux, reading from a disk is very slow compared to accessing real memory. In addition, it is common to read the same part of a disk several times during relatively short periods of time. For example, one might first read an e-mail message, then read the letter into an editor when replying to it, then make the mail program read it again when copying it to a folder. Or, consider how often the command ls might be run on a system with many users. By reading the information from disk only once and then keeping it in memory until no longer needed, one can speed up all but the first read. This is called disk buffering, and the memory used for the purpose is called the buffer cache.

Unlike (Windows) other operating systems, Linux administers memory the smartest way it can.

Since unused memory is next to worthless, the filesystem takes whatever memory is left and caches it in order to speed up disk access. When the cache fills up, the data that has been unused for the longest time is discarded and the memory thus freed is used for the new data.

Whenever an application needs memory, the kernel makes the cache smaller; You do not need to do anything to make use of the cache, it happens completely automatically.

Freeing memory buffer does not make your programs faster… Actually it makes disk access slower.

BUT if for some reason (kernel debugging for example) you want to force the buffer to be freed, you need to set the drop_caches value to 1:

$ echo 1 > /proc/sys/vm/drop_caches
Issuing this command will release all the cached memory and also will stop collecting I/O buffer blocks. Let’s see an example of the effect:




Under normal situations, most of the memory is already cached by the system. But if we force the system to free the memory, you can see in the graph how the memory is suddenly dropped.

The technical details of how this works are explained on the Linux API

2010年6月2日 星期三

initsript


在某些原因下,有些自己寫的程式不想放在/etc/init.d下當一個 service來啟動
而是放在/etc/inittab中來啟動
但此時如果要對這個daemon程式進行系統調整時,會有困難
例如ulimit的控制項
因為一般我們指令在執行ulimit都是當下狀況,在bash下產生的效果
而要讓這個ulimit發生效果之前,其實透過/etc/inittab啟動的程式,早就起來了
也就是先後順序的問題
所以應該要找到一個比/etc/inittab啟動前更早的東西來執行
原本是想,把這個daemon用一個scripts包起來
而這個daemon執行之前,先執行ulimit -n 8192(例如要把openfiles上限開到8192)
結果.....殘念,不知為何不能生效

後來才發現有一個叫 initscript的東西,可以man initscript來看看
也新增一個/etc/initscript來讓init在執行/etc/inittab前先執行/etc/initscript
這樣就能有效讓ulimit生效了
預設沒有/etc/initscript這個檔案,可以man initscript的內容,拿來新增這個檔案
#man initscript
:
:
#
# initscript Executed by init(8) for every program it
# wants to spawn like this:
#
# /bin/sh /etc/initscript
#

# Set umask to safe level, and enable core dumps.
umask 022
ulimit -c 2097151
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

# Increase the hard filedescriptor limit for all processes
# to 8192. The soft limit is still 1024, but any unpriviliged
# process can increase it’s soft limit up to the hardlimit
# with "ulimit -Sn xxx" (needs a 2.2.13 or later Linux kernel).
ulimit -Hn 8192

# Execute the program.
eval exec "$4"
先把他存到/etc/initscript
然後,修改ulimit -Hn 8192成為ulimit -n 8192即可
eval exec "$4"這行不可以漏掉,否則/etc/inittab會沒執行到
#ls -l /etc/initscript
-rw-r--r-- 1 root root 581 6¤ë 17 2009 /etc/initscript

2010年2月25日 星期四

processes fork and swap space

今天在Sun Solaris上進行壓力測試, 想當然爾跑出了一堆程式, 可是卻停在第20xx後程式就fork不出來了。可憐的是,程式的原始碼不是自己持有,也就是說跑的是別人家的程式,實在很難抓問題,尤其在沒有任何其他明顯線索下。沒辦法了,自己寫一支程式來測試看看嘍,好在之前有在Linux寫了一支壓力測試程式,重新Make後,就趕上架去處理吧。
RUN了2圈後,很快發現fork error , errno=12 (ENOMEM), 從man page上可以發現是swap space的問題,check一下指令
swap -l :查詢swap 空間設定為多少
swap -s:目前當下剩下的swap space 還有多少可用
在測試前後比較,明顯發現swap空間的不足,二話不說,當然是增加swap嘍。

話雖然這樣就解決了,只是fork程式跟swap空間有什麼關係呢
以下摘錄自: http://bbs.nsysu.edu.tw/txtVersion/treasure/linux/M.1013884061.A.html

BSD對swap space的處理頗為保守. 要求所有在主記憶體的page
在配置前都必須要先有一塊swap space. 所以swap space的大
小限制了可以執行的程式數量.不過這也保證程式只有在fork或
exec時才會發生記憶體不足的現象, 而不會執行到一半要被swap
出去, 卻找不到swap space可用的窘況.也就是說如果你的電腦有
64MB的記憶體,但是只劃了16MB的記憶體,這樣的系統只願意讓你使
用16MB而已, 這也是有些系統管理的書籍建議你swap space不要比
main memory小的原因.


這句話也為我自己解釋了長久以來在上課時,老師總要我們把swap空間開DRAM的1~2倍的原因

目前知道跟process 數量上限直接有關的
1. 實體記憶體大小
2.Swap 大小
3.System configuration(ulimit , plimit...etc)

那哪些是間接的呢
例如CPU idle, process使用的共用資源限制(例如程式去搶share memory resource)或socket resource...etc

不知道還有沒有別的?!

PS.真是小時不努力,老大徒傷悲

文章分類