转://linux下hugepages理解
就Linux应用程序而言,使用的都是虚拟地址,当应用程序读写一个指定的虚拟地址时,内存管理单元会自动进行虚拟地址到物理地址的转换。一个虚拟地址可以映射到多个物理地址,但当前映射到哪一个物理地址取决于当前的页表(Page Table,一个虚拟地址到物理地址的映射转换表)内容,页表存储在主存储器中,查询速度相对比较慢。为了提高地址转换性能,大多数体系架构都提供一个快速查找缓冲TLB(Translation Lookaside Buffer),TLB读写速度非常快,比如在X86体系架构上,TLB和普通的CPU CACHE并没有本质区别,只不过TLB专职用于缓存页表数据,而普通的CPU CACHE缓存实际的代码指令或数据。TLB缓冲了最近使用过的页表项,在进行虚拟地址到物理地址的转换时先查这个TLB缓冲,只有当查找TLB缓冲失败(TLB miss)后才再去查普通页表(好像有的架构是同时进行查找?)。当然,根据局部性原理,大多数情况下应该都是查找TLB缓冲命中(TLB hit)的,所以性能得以大大提升。这整个具体的页表查找与地址转换过程不是文本描述的重点,但我们需知道如下几点:
1,TLB缓冲能大大提升虚拟地址到物理地址的转换速度。
2,TLB缓冲大小有限,只能缓存一定量的页表项目(Entry)。
3,如果一个页越大,那么一个页表项目就能表示越多的地址空间,整个TLB缓冲命中的几率就越大。
在Linux平台上,页大小普遍为4K,但根据硬件架构的不同,Linux内核也支持更大的内存页,也就是本文要介绍的HugeTLB特性。
要使用HugeTLB特性,当然需要首先打开内核的相关编译选项:
1
2
3
4
5
6
7
8
9
10
11
|
[root@localhost ~]# uname -a Linux localhost.localdomain 2.6.38.8 #4 SMP Mon Oct 31 20:49:48 CST 2011 x86_64 x86_64 x86_64 GNU/Linux [root@localhost ~]# cat /usr/src/linux-`uname -r`/.config | grep HUGETLB CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y [root@localhost ~]# free -m total used free shared buffers cached Mem: 2007 1920 87 0 1 10 -/+ buffers/cache: 1908 99 Swap: 2015 33 1982 [root@localhost ~]# |
查看HugePages信息:
1
2
3
4
5
6
7
|
[root@localhost ~]# cat /proc/meminfo | grep Huge HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB [root@localhost ~]# |
其中:
HugePages_Total:系统当前总共拥有的HugePages数目。
HugePages_Free:系统当前总共拥有的空闲HugePages数目。
HugePages_Rsvd:系统当前总共保留的HugePages数目,更具体点就是指程序已经向系统申请,但是由于程序还没有实质的HugePages读写操作,因此系统尚未实际分配给程序的HugePages数目。
HugePages_Surp:指超过系统设定的常驻HugePages数目的数目。
Hugepagesize:每一页HugePages的大小。
虽然尝试对上面这几个字段解释了一通,但HugePages_Rsvd和HugePages_Surp貌似仍然不够清楚,下面我们以实例数据来看,不过在此之前需要讲解另外几个内核参数:
1
2
3
4
5
6
7
|
[root@localhost ~]# cat /proc/sys/vm/nr_hugepages 0 [root@localhost ~]# cat /proc/sys/vm/nr_hugepages_mempolicy 0 [root@localhost ~]# cat /proc/sys/vm/nr_overcommit_hugepages 0 [root@localhost ~]# |
其中:/proc/sys/vm/nr_hugepages,就是用于设定系统拥有的常驻HugePages数目的/proc接口,可读可写,比如修改常驻HugePages数目为10:
1
2
3
4
5
6
7
8
|
[root@localhost ~]# echo 10 > /proc/sys/vm/nr_hugepages [root@localhost ~]# cat /proc/meminfo | grep Huge HugePages_Total: 10 HugePages_Free: 10 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB [root@localhost ~]# |
这个值当然并不是echo多少就是多少,它根据系统当前的可用内存来计算,比如如下,2G内存当然不可能会有1000000个HugePages,系统根据当前可用物理内存计算出可以组成的HugePages数目为899:
1
2
3
4
5
6
7
8
|
[root@localhost ~]# echo 1000000 > /proc/sys/vm/nr_hugepages [root@localhost ~]# cat /proc/meminfo | grep Huge HugePages_Total: 899 HugePages_Free: 899 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB [root@localhost ~]# |
接口/proc/sys/vm/nr_hugepages_mempolicy和/proc/sys/vm/nr_hugepages的功用类似,但是它只出现在NUMA系统上,用于更精细的HugePages申请分配。比如,对于一个具有2个NUMA节点的系统,申请100个HugePages页面(先清0,以便重新生成HugePages页面):
1
2
3
4
5
6
7
8
9
10
|
[root@localhost ~]# echo 0 > /proc/sys/vm/nr_hugepages [root@localhost ~]# echo 100 > /proc/sys/vm/nr_hugepages [root@localhost ~]# cat /sys/devices/ system /node/node*/meminfo | fgrep Huge Node 0 HugePages_Total: 50 Node 0 HugePages_Free: 50 Node 0 HugePages_Surp: 0 Node 1 HugePages_Total: 50 Node 1 HugePages_Free: 50 Node 1 HugePages_Surp: 0 [root@localhost ~]# |
/proc/sys/vm/nr_hugepages接口会按照当前修改nr_hugepages的进程的NUMA策略进行HugePages分配,当然,默认情况下就是系统当前所有在线NUMA节点平均分配这些HugePages,除非那个NUMA节点本身没有足够的可用连续内存来生成HugePages,那么此时HugePages将由另外一个NUMA节点生成。
通过/proc/sys/vm/nr_hugepages_mempolicy接口,可以指定HugePages页面具体由哪个NUMA节点生成:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
[root@localhost ~]# echo 0 > /proc/sys/vm/nr_hugepages [root@localhost ~]# numactl -m 0 echo 40 >/proc/sys/vm/nr_hugepages_mempolicy [root@localhost ~]# cat /sys/devices/ system /node/node*/meminfo | fgrep Huge Node 0 HugePages_Total: 40 Node 0 HugePages_Free: 40 Node 0 HugePages_Surp: 0 Node 1 HugePages_Total: 0 Node 1 HugePages_Free: 0 Node 1 HugePages_Surp: 0 [root@localhost ~]# numactl -m 1 echo 60 >/proc/sys/vm/nr_hugepages_mempolicy [root@localhost ~]# cat /sys/devices/ system /node/node*/meminfo | fgrep Huge Node 0 HugePages_Total: 40 Node 0 HugePages_Free: 40 Node 0 HugePages_Surp: 0 Node 1 HugePages_Total: 20 Node 1 HugePages_Free: 20 Node 1 HugePages_Surp: 0 [root@localhost ~]# echo 80 >/proc/sys/vm/nr_hugepages_mempolicy [root@localhost ~]# cat /sys/devices/ system /node/node*/meminfo | fgrep Huge Node 0 HugePages_Total: 50 Node 0 HugePages_Free: 50 Node 0 HugePages_Surp: 0 Node 1 HugePages_Total: 30 Node 1 HugePages_Free: 30 Node 1 HugePages_Surp: 0 [root@localhost ~]# numactl -m 1 echo 100 >/proc/sys/vm/nr_hugepages [root@localhost ~]# cat /sys/devices/ system /node/node*/meminfo | fgrep Huge Node 0 HugePages_Total: 60 Node 0 HugePages_Free: 60 Node 0 HugePages_Surp: 0 Node 1 HugePages_Total: 40 Node 1 HugePages_Free: 40 Node 1 HugePages_Surp: 0 [root@localhost ~]# |
上面先清0,以便系统重新生成HugePages页面,前40个HugePages页面全部在NUMA节点0上生成,而后20个(即60-40)HugePages页面全部在NUMA节点1上生成,再接下来的20个(即80-60)HugePages页面平均由NUMA节点0和1上生成,即此时虽然使用的nr_hugepages_mempolicy接口,但由于没有指定NUMA策略,所以默认就是平均分配,最后即便是指定了NUMA策略,但由于使用的是nr_hugepages接口,所以仍然是平均分配。上面是增加HugePages页面的情况,减少的话也是类似:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
[root@localhost ~]# numactl -m 1 echo 80 >/proc/sys/vm/nr_hugepages [root@localhost ~]# cat /sys/devices/ system /node/node*/meminfo | fgrep Huge Node 0 HugePages_Total: 50 Node 0 HugePages_Free: 50 Node 0 HugePages_Surp: 0 Node 1 HugePages_Total: 30 Node 1 HugePages_Free: 30 Node 1 HugePages_Surp: 0 [root@localhost ~]# numactl -m 1 echo 60 >/proc/sys/vm/nr_hugepages_mempolicy [root@localhost ~]# cat /sys/devices/ system /node/node*/meminfo | fgrep Huge Node 0 HugePages_Total: 50 Node 0 HugePages_Free: 50 Node 0 HugePages_Surp: 0 Node 1 HugePages_Total: 10 Node 1 HugePages_Free: 10 Node 1 HugePages_Surp: 0 [root@localhost ~]# numactl -m 0 echo 35 >/proc/sys/vm/nr_hugepages_mempolicy [root@localhost ~]# cat /sys/devices/ system /node/node*/meminfo | fgrep Huge Node 0 HugePages_Total: 25 Node 0 HugePages_Free: 25 Node 0 HugePages_Surp: 0 Node 1 HugePages_Total: 10 Node 1 HugePages_Free: 10 Node 1 HugePages_Surp: 0 [root@localhost ~]# |
第一个是平均减少,各自减少10个,第二个是仅由NUMA节点1减少20个,第三个是仅由NUMA节点0减少25个。当然,系统也提供有直接查看/设置某个NUMA节点上HugePages页面分配的接口:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[root@localhost ~]# grep ^ /sys/devices/ system /node/node*/hugepages /*/* /sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages:25 /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages:25 /sys/devices/system/node/node0/hugepages/hugepages-2048kB/surplus_hugepages:0 /sys/devices/system/node/node1/hugepages/hugepages-2048kB/free_hugepages:10 /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages:10 /sys/devices/system/node/node1/hugepages/hugepages-2048kB/surplus_hugepages:0 [root@localhost ~]# echo 36 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages [root@localhost ~]# cat /sys/devices/system/node/node*/ meminfo | fgrep Huge Node 0 HugePages_Total: 36 Node 0 HugePages_Free: 36 Node 0 HugePages_Surp: 0 Node 1 HugePages_Total: 10 Node 1 HugePages_Free: 10 Node 1 HugePages_Surp: 0 [root@localhost ~]# |
关于NUMA节点HugePages页面分配以及numactl命令还有更多细节,请参考hugetlbpage.txt以及man手册。
另一个/proc接口:/proc/sys/vm/nr_overcommit_hugepages,表示程序申请HugePages可超过常驻HugePages数目的最大数目。一个使用HugePages的应用程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
/** * FileName: eg1.c */ #include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdlib.h> #define MB_1 (1024*1024) #define MB_8 (8*MB_1) char *a; int shmid; void init_hugepage_seg() { shmid = shmget(1, MB_8, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W); if ( shmid < 0 ) { perror ( "shmget error!" ); exit (1); } printf ( "init_hugepage_seg shmid: 0x%x.\n" , shmid); a = shmat(shmid, 0, 0); if (a == ( char *)-1) { perror ( "Shared memory attach failure!\n" ); shmctl(shmid, IPC_RMID, NULL); exit (2); } } void wr_to_array() { int i; for ( i=0 ; i<MB_8 ; i++) { a[i] = 'A' ; } } void rd_from_array() { int i, count = 0; for ( i=0 ; i<MB_8 ; i++) if (a[i] == 'A' ) count++; if (count==i) printf ( "HugeTLB read success.\n" ); else printf ( "HugeTLB read failed.\n" ); } int main( int argc, char *argv[]) { init_hugepage_seg(); printf ( "Hugepage memory segment initialized!\n" ); printf ( "Press any key to write/read memory!\n" ); getchar (); wr_to_array(); rd_from_array(); printf ( "Press any key to free hugepage and exit!\n" ); getchar (); shmctl(shmid, IPC_RMID, NULL); return 0; } |
编译它为执行程序eg1,eg1使用8M内存,即需要4页HugePages,设定常驻HugePages数为3,可超出常驻HugePages使用数为0,此时执行eg1会提示内存分配失败:
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@localhost huge]# gcc -o eg1 eg1.c [root@localhost huge]# echo 3 > /proc/sys/vm/nr_hugepages [root@localhost huge]# echo 0 > /proc/sys/vm/nr_overcommit_hugepages [root@localhost huge]# cat /proc/meminfo | grep Huge HugePages_Total: 3 HugePages_Free: 3 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB [root@localhost huge]# ./eg1 shmget error!: Cannot allocate memory [root@localhost huge]# |
如果设定常驻HugePages数大于等于4,eg1当然可以执行成功,但也可以设定nr_overcommit_hugepages大于等于1同样也可以让eg1成功执行,即只要nr_hugepages + nr_overcommit_hugepages大于等于4,此处eg1就可成功执行:
1
2
3
4
5
6
7
8
9
10
11
|
[root@localhost huge]# echo 3 > /proc/sys/vm/nr_hugepages [root@localhost huge]# echo 1 > /proc/sys/vm/nr_overcommit_hugepages [root@localhost huge]# ./eg1 init_hugepage_seg shmid: 0x90000. Hugepage memory segment initialized! Press any key to write/read memory! HugeTLB read success. Press any key to free hugepage and exit ! [root@localhost huge]# |
回过头来看HugePages_Total、HugePages_Free、HugePages_Rsvd、HugePages_Surp这四个字段:
HugePages_Total大多数情况下等于/proc/sys/vm/nr_hugepages(后面用nr_hugepages表示)的值,但当/proc/sys/vm/nr_overcommit_hugepages(后面用nr_overcommit_hugepages表示)大于0时,HugePages_Total会超过nr_hugepages,但肯定小于等于nr_hugepages + nr_overcommit_hugepages,即:nr_hugepages <= HugePages_Total <= nr_hugepages + nr_overcommit_hugepages。
HugePages_Free、HugePages_Rsvd、HugePages_Surp来看实例,先做一些设置:
1
2
3
4
5
6
7
8
9
|
[root@localhost ~]# echo 3 > /proc/sys/vm/nr_hugepages [root@localhost ~]# echo 2 > /proc/sys/vm/nr_overcommit_hugepages [root@localhost ~]# cat /proc/meminfo | grep Huge HugePages_Total: 3 HugePages_Free: 3 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB [root@localhost ~]# |
然后,另开一个shell终端执行eg1程序:
1
2
3
4
|
[root@localhost huge]# ./eg1 init_hugepage_seg shmid: 0xa0000. Hugepage memory segment initialized! Press any key to write/read memory! |
就让eg1程序停在这,此时eg1程序已经执行了init_hugepage_seg();,即已经向系统申请4页HugePages,但还没有进行实质内存读写操作wr_to_array();/rd_from_array();,回到之前的shell终端看HugePage信息:
1
2
3
4
5
6
7
|
[root@localhost ~]# cat /proc/meminfo | grep Huge HugePages_Total: 4 HugePages_Free: 4 HugePages_Rsvd: 4 HugePages_Surp: 1 Hugepagesize: 2048 kB [root@localhost ~]# |
此时HugePages_Total值为4,为eg1程序申请的HugePages数;HugePages_Free为4,表示系统尚未把这4页HugePages分配给eg1程序,所以它们都处于free状态,值得注意的是,虽然它们处于free状态,但已经不能再分配作为他用,要测试的话只需把前面eg1.c文件拷贝为eg2.c,并修改其中shmget函数的key值为2,然后gcc编译为eg2,在当前这个状态下再执行eg2则会提示:“shmget error!: Cannot allocate memory”;HugePages_Rsvd也为4,表示程序eg1已经向系统提出申请但尚未获得实际分配的HugePages数;HugePages_Surp为1,表示超过系统设定的常驻HugePages数目的数目,即是:HugePages_Total(当前是4) - nr_hugepages(当前是3)。
回到执行eg1程序的shell终端,按一下键盘让eg1程序进行实际读写操作后再回到之前的shell终端看HugePage信息:
1
2
3
4
5
6
7
|
[root@localhost huge]# ./eg1 init_hugepage_seg shmid: 0xa8000. Hugepage memory segment initialized! Press any key to write/read memory! HugeTLB read success. Press any key to free hugepage and exit ! |
此时eg1程序已经进行了实际读写操作,但是尚未释放HugePages内存:
1
2
3
4
5
6
7
|
[root@localhost ~]# cat /proc/meminfo | grep Huge HugePages_Total: 4 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 1 Hugepagesize: 2048 kB [root@localhost ~]# |
所以看到的HugePages_Total等于4,HugePages_Free等于0,表示4页HugePages都被eg1程序使用中;HugePages_Rsvd等于0自然是表示eg1程序已经获得了HugePages内存分配。HugePages_Surp为1,表示当前超过系统设定的常驻HugePages数目的数目还是1。
eg1程序退出后自然数据又都恢复成初始状态了,注意此时HugePages_Surp归为0了,表示那些非常驻HugePages被实时的释放回系统了,另外,如果在它们还没有释放回系统此前修改了常驻HugePages数目,那么这些HugePages_Surp的HugePages会优先被选择成为常驻HugePages:
1
2
3
4
5
6
7
8
9
|
[root@localhost huge]# ./eg1 init_hugepage_seg shmid: 0xa8000. Hugepage memory segment initialized! Press any key to write/read memory! HugeTLB read success. Press any key to free hugepage and exit ! [root@localhost huge]# |
1
2
3
4
5
6
7
|
[root@localhost ~]# cat /proc/meminfo | grep Huge HugePages_Total: 3 HugePages_Free: 3 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB [root@localhost ~]# |
一般情况下,几个不等式为:
nr_hugepages <= HugePages_Total <= nr_hugepages + nr_overcommit_hugepages
HugePages_Free <= HugePages_Total
HugePages_Rsvd <= HugePages_Free
HugePages_Surp = HugePages_Total - nr_hugepages <= nr_overcommit_hugepages
那么特殊情况下,比如当前nr_hugepages为100,使用中的HugePages数目也为100,如果此时修改nr_hugepages为80,那么即便当前nr_overcommit_hugepages为0,这多出的使用中的20个HugePages也会被计算在HugePages_Surp中,同时此时也不再能够申请HugePages内存了,直到满足上面几个不等式为止。
被用作HugePages的内存页是不会被系统交换出去(swapped out)的,并且由于HugePages需要更大的连续物理内存,所以在系统启动时更容易获得更多的HugePages内存,并且还能尽量保证这些HugePages内存页连续,通过通过添加对应的boot kernel参数来实现这点:
1
2
3
|
[root@localhost ~]# cat /proc/cmdline ro root=/dev/mapper/VolGroup-lv_root rd_LVM_LV=VolGroup/lv_root rd_LVM_LV=VolGroup/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us crashkernel=auto rhgb quiet hugepages=10 hugepagesz=2M default_hugepagesz=4M [root@localhost ~]# |
如上面当前内核boot命令行参数设定HugePages内存页10个(hugepages=10),默认HugePages内存页大小为4M,但Linux X86-64不支持,所以看到的Hugepagesize仍然只是2M(2048 kB)。/proc/sys/vm/nr_hugepages接口改变的是默认HugePages内存页大小的数目,如果系统支持多种大小的HugePages,改变它们各自的数目需要/sys接口:
1
2
3
|
[root@localhost ~]# ls /sys/kernel/mm/hugepages -F hugepages-2048kB/ [root@localhost ~]# |
我的系统只有一种大小的HugePages,所以只有一个hugepages-2048kB/目录,如果有多种大小的HugePages,那么自然就会有多个hugepages-${size}kB/这样的目录。每一个目录下存在同样命名的一些文件,其中有三个可读写,通过这几个可读写的接口便可做相应的修改设置,其它只读:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
[root@localhost ~]# cat /proc/sys/vm/nr_hugepages 10 [root@localhost ~]# cat /proc/sys/vm/nr_overcommit_hugepages 0 [root@localhost ~]# cat /proc/meminfo | grep Huge HugePages_Total: 10 HugePages_Free: 10 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB [root@localhost ~]# grep ^ /sys/kernel/mm/hugepages/hugepages-2048kB/* /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages:10 /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages:10 /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages_mempolicy:10 /sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages:0 /sys/kernel/mm/hugepages/hugepages-2048kB/resv_hugepages:0 /sys/kernel/mm/hugepages/hugepages-2048kB/surplus_hugepages:0 [root@localhost ~]# ls -l /sys/kernel/mm/hugepages/hugepages-2048kB/ total 0 -r--r--r--. 1 root root 4096 Jan 25 06:31 free_hugepages -rw-r--r--. 1 root root 4096 Jan 25 06:31 nr_hugepages -rw-r--r--. 1 root root 4096 Jan 25 06:31 nr_hugepages_mempolicy -rw-r--r--. 1 root root 4096 Jan 25 06:31 nr_overcommit_hugepages -r--r--r--. 1 root root 4096 Jan 25 06:31 resv_hugepages -r--r--r--. 1 root root 4096 Jan 25 06:31 surplus_hugepages |
转://linux下hugepages理解的更多相关文章
- 对于linux下system()函数的深度理解(整理)
原谅: http://blog.sina.com.cn/s/blog_8043547601017qk0.html 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同 ...
- 转:对于linux下system()函数的深度理解(整理)
这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为 ...
- (笔记)Linux下system()函数的深度理解(整理)
注:从其它地方转的非常好的一篇文章,值得深究! 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数 ...
- Linux下对于makefile的理解
什么是makefile呢?在Linux下makefile我们可以把理解为工程的编译规则.一个工程中源文件不计数,其按类型.功能.模块分别放在若干个目录中,makefile定义了一系列的规则来指定,那些 ...
- 深入理解LINUX下动态库链接器/加载器ld-linux.so.2
[ld-linux-x86-64.so.2] 最近在Linux 环境下开发,搞了好几天 Compiler 和 linker,觉得有必要来写一篇关于Linux环境下 ld.so的文章了,google上搜 ...
- Linux下为何都是文件的理解
所谓“文件”,就是在我们的电脑中,以实现某种功能.或某个软件的部分功能为目的而定义的一个单位. Linux都是以文件的形式存在,当我们访问某个文件(Linux中的文件有目录,连接,普通文本),由于Li ...
- 从汇编角度来理解linux下多层函数调用堆栈执行状态
注:在linux下开发经常使用的辅助小工具: readelf .hexdump.od.objdump.nm.telnet.nc 等,详细能够man一下. 我们用以下的C代码来研究函数调用的过程. C ...
- Linux 下线程的理解
2017-04-03 最近深入研究了下Linux线程的问题,发现自己之前一直有些许误解,特记之…… 关于Linux下的线程,各种介绍Linux的书籍都没有深入去解释的,或许真的如书上所述,Linux本 ...
- 转:// LINUX下为ORACLE数据库设置大页--hugepage
一.在解释什么情况下需要开启大页和为啥需要开启大页前先了解下Linux下页的相关的知识:以下的内容是基于32位的系统,4K的内存页大小做出的计算1)目录表,用来存放页表的位置,共包含1024个目录en ...
随机推荐
- 创建Aurelia项目
什么是Aurelia? Aurelia 是一个新的开源的,基于web标准的mvvm框架,是一个现代化的js模块的集合. Aurelia提供了丰富的plugin,例如国际化,验证,模态框,UI可视化等. ...
- 使用laravel框架开发接口时ajax post请求报错419
nginx服务器,使用laravel框架开发后台接口.get请求正常,但是post请求一直报错.H5和APP都不成功,code=419. 解决办法: 找到 VerifyCsrfToken.php文件( ...
- jfinal框架学习过程
刚刚学习jfinal,通过一天左右的时间大体上理解了这个框架的用法,我对他的理解是JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速.代码量少.学习简单.功 ...
- 向后台提交数据:cookie,secure_cookie,
向后台提交数据除了前端url,form表单,Ajax外还可以用cookie,secure_cookie,提交更多信息可以在用cookie基础上用session, cookie,secure_cooki ...
- CSS3布局之box-flex的使用
语法: box-flex:<number> 其中number取值:使用浮点数指定对象所分配其父元素剩余空间的比例.设置或检索伸缩盒对象的子元素如何分配其剩余空间.(伸缩盒最老版本) htm ...
- SAP WM 有无保存WM Level历史库存的Table?
SAP WM 有无保存WM Level历史库存的Table? 前日下班回家的路上,收到一个前客户内部顾问同行发过来的微信,问我在SAP系统里哪个表是用来存储WM Level历史库存的. 这个问题问住了 ...
- js获取选中日期的当周的周一和周日
js获取选中日期的当周的周一和周日 第一种方法(推荐): function getWeekStr(str) { // 将字符串转为标准时间格式 str2 = Date.parse(str); let ...
- PHP的匿名函数和闭包
匿名函数 // Example1 $func = function( $param ) { echo $param; }; $func( 'some string' );//输出:some strin ...
- [20181204]低版本toad 9.6直连与ora-12505.txt
[20181204]低版本toad 9.6直连与ora-12505.txt --//我们生产系统还保留有一台使用AMERICAN_AMERICA.US7ASCII字符集的数据库,这样由于toad新版本 ...
- Spring MVC HelloWorld入门及运行机制 (一)
完整的项目案例: springmvc.zip 介绍 SpringMVC是一款Web MVC框架. 它跟Struts框架类似,是目前主流的Web MVC框架之一. 文章通过实例来介绍SpringMVC的 ...