香蕉与打火机

机器学习和AI的时代来了

Latest Posts

oracle rac 常用命令

原文:http://blog.sina.com.cn/s/blog_683e8ddf0100p0mm.html

1、查看RAC数据库整体状况
$srvctl status database -d orcl
注:orcl为数据库名,可通过查询2获得
2、查询所有配置的数据库
$srvctl config database
3、显示RAC数据库的配置
srvctl config database -d orcl
4、显示指定集群数据库的所有服务
srvctl config service -d orcl
5、查询指定实例状况
srvctl status instance -d orcl -i orcl2

注:orcl2为实例名
6、查询在数据库全局命名服务的状态
srvctl status service -d orcl -s orcltest

注:orcltest为服务名
7、查询指定节点上应用程序的状态
srvctl status nodeapps -n linux1

linux为集群中的一个节点名
8、ASM实例的状态
srvctl status asm -n linux1
注:ASM:Automatic Storage Management
9、查询节点应用程序的配置-(VIP、GSD、ONS、监听器)
srvctl config nodeapps -n linux1 -a -g -s -l
注:VIP:virtual IP
   GSD:Global Service Daemon
   ONS:Oracle Notification Service
10、查询集群中所有正在运行的实例
SELECT
inst_id
, instance_number inst_no
, instance_name inst_name
, parallel
, status
, database_status db_status
, active_state state
, host_name host
FROM gv$instance
ORDER BY inst_id;

其他以后再补充。

win 2008 远程桌面用户自动注销

原文:http://baohua.me/operating-system/windows-configure-disconnect-user-auto-logoff/

在服务器上进行维护时,经常会遇到很多用户登录服务器之后,没有注销就直接断开了与服务器的连接,并且该用户一直在系统上处于断开状态,没有释放用户使用的资源。

对于没有配置终端授权服务的服务器来说,每台机器最多只允许登录服务器的用户数就那么几个而已,具体支持数量跟操作系统的版本有关系。

其实要配置自动注销,相对来说比较简单。
在<管理工具>中打开<远程桌面服务>的<远程桌面会话主机配置>工具

配置服务器的RDP-Tcp属性

打开RDP-Tcp属性


选择<会话>,将改写用户设置进行配置,一般建议配置如下,可根据实际需求进行更改。(时间太短就是坑爹呢)

配置完毕之后,选择应用,并确定。使用用户帐号重新登录到系统之后就会生效。

linux 账号管理与ACL权限设定

参考(鸟哥):http://linux.vbird.org/linux_basic/0410accountmanager.php

1.账号与群组

1.1使用者识别码

使用者识别码即UID(User ID)与GID(Group ID)。

linux是通过数字ID来识别用户及组的。

用户为账号的命名仅仅是为了便于用户记忆。命名及账号ID的对应在/etc/passwd中。

如下,banana账号,UID=500,GID=500。

查看banana的home目录的所属,用户和组都是banana。

现修改banana在/etc/passwd中的UID为2000,使目录号不能在/etc/passwd文件中找到对应的用户名。

如上,再看/home/banana/目录,其用户变成了500。因为linux系统对目录的登记都是使用UID+GID,当管理员查看的时候,linux再持着ID去/etc/passwd文件找到管理员登记的命名,然后将该命名返回给管理员。

由于我们修改了/etc/passwd文件中500这个用户的记录条目,linux持着目录所有者登记的UID号500到/etc/passwd文件中查不到记录(原UID500改为2000),所以只好将UID本身返回给管理员。

完成本实验后,我们将修改复原,避免遗留错误。

Tips:
舉例來說,如果上面的測試最後一個步驟沒有將 2000 改回原本的 UID,那麼當 dmtsai 下次登入時將沒有辦法進入自己的家目錄! 因為他的 UID 已經改為 2000 ,但是他的家目錄 (/home/dmtsai) 卻記錄的是 503 ,由於權限是 700 , 因此他將無法進入原本的家目錄!是否非常嚴重啊?——鸟哥

1.2使用者账号

linux用户登录到shell界面进行操作的过程如下:

  • 到达login界面(方式:1.tty1~tty7终端;2.ssh远程登录);
  • 输入密码;
  • 登入或退出。

输入密码后,系统的操作:

  1. 在/etc/passwd中查找用户指定的账号,没有跳出。有则一并在/etc/group中取出用户的UID、GID及home目录位置。
  2. 核对密码:持着前面找出的UID在/etc/shadow文件中对应的条目,对比用户输入的密码是否与记录匹配。
  3. 前述都正确,则向用户开放shell,并将shell目录设定为前面取出的home目录。

由上可知,/etc/passwd、/etc/shadow文件非常重要,备份系统时需要备份。

/etc/passwd结构

每行代表一个账号,除了管理员添加的账号,还有系统账号为系统内建账号。

用“:”分隔,一共有7个字段。按顺序依次是:

 

  1. 帳號名稱
    就是帳號啦!用來對應 UID 的。例如 root 的 UID 對應就是 0 (第三欄位);
  2. 密碼
    早期 Unix 系統的密碼就是放在這欄位上!但是因為這個檔案的特性是所有的程序都能夠讀取,這樣一來很容易造成密碼資料被竊取, 因此後來就將這個欄位的密碼資料給他改放到/etc/shadow 中了。所以這裡你會看到一個『 x 』,呵呵!
  3. UID
    這個就是使用者識別碼囉!通常 Linux 對於 UID 有幾個限制需要說給您瞭解一下:

    id 範圍 該 ID 使用者特性
    0
    (系統管理員)
    當 UID 是 0 時,代表這個帳號是『系統管理員』! 所以當你要讓其他的帳號名稱也具有 root 的權限時,將該帳號的 UID 改為 0 即可。 這也就是說,一部系統上面的系統管理員不見得只有 root 喔! 不過,很不建議有多個帳號的 UID 是 0 啦~
    1~499
    (系統帳號)
    保留給系統使用的 ID,其實除了 0 之外,其他的 UID 權限與特性並沒有不一樣。預設 500 以下的數字讓給系統作為保留帳號只是一個習慣。由於系統上面啟動的服務希望使用較小的權限去運作,因此不希望使用 root 的身份去執行這些服務, 所以我們就得要提供這些運作中程式的擁有者帳號才行。這些系統帳號通常是不可登入的, 所以才會有我們在第十一章提到的 /sbin/nologin 這個特殊的 shell 存在。根據系統帳號的由來,通常系統帳號又約略被區分為兩種:
    1~99:由 distributions 自行建立的系統帳號;
    100~499:若使用者有系統帳號需求時,可以使用的帳號 UID。
    500~65535
    (可登入帳號)
    給一般使用者用的。事實上,目前的 linux 核心 (2.6.x 版)已經可以支援到 4294967295 (2^32-1) 這麼大的 UID 號碼喔!

    上面這樣說明可以瞭解了嗎?是的, UID 為 0 的時候,就是 root 呦!所以請特別留意一下你的 /etc/passwd 檔案!

  4. GID
    這個與 /etc/group 有關!其實 /etc/group 的觀念與 /etc/passwd 差不多,只是他是用來規範群組名稱與 GID 的對應而已!
  5. 使用者資訊說明欄
    這個欄位基本上並沒有什麼重要用途,只是用來解釋這個帳號的意義而已!不過,如果您提供使用 finger 的功能時, 這個欄位可以提供很多的訊息呢!本章後面的 chfn 指令會來解釋這裡的說明。
  6. 家目錄
    這是使用者的家目錄,以上面為例, root 的家目錄在 /root ,所以當 root 登入之後,就會立刻跑到 /root 目錄裡頭啦!呵呵! 如果你有個帳號的使用空間特別的大,你想要將該帳號的家目錄移動到其他的硬碟去該怎麼作? 沒有錯!可以在這個欄位進行修改呦!預設的使用者家目錄在 /home/yourIDname
  7. Shell
    我們在第十一章 BASH 提到很多次,當使用者登入系統後就會取得一個 Shell 來與系統的核心溝通以進行使用者的操作任務。那為何預設 shell 會使用 bash 呢?就是在這個欄位指定的囉! 這裡比較需要注意的是,有一個 shell 可以用來替代成讓帳號無法取得 shell 環境的登入動作!那就是 /sbin/nologin 這個東西!這也可以用來製作純 pop 郵件帳號者的資料呢!

/etc/shadow结构

这是存密码的文件。是从/etc/passwd第二栏分出来的,

一共9个字段,按顺序依次是:

  1. 帳號名稱
    由於密碼也需要與帳號對應啊~因此,這個檔案的第一欄就是帳號,必須要與 /etc/passwd 相同才行!
  2. 密碼
    這個欄位內的資料才是真正的密碼,而且是經過編碼的密碼 (加密) 啦! 你只會看到有一些特殊符號的字母就是了!需要特別留意的是,雖然這些加密過的密碼很難被解出來, 但是『很難』不等於『不會』,所以,這個檔案的預設權限是『-rw——-』或者是『-r——–』,亦即只有 root 才可以讀寫就是了!你得隨時注意,不要不小心更動了這個檔案的權限呢!另外,由於各種密碼編碼的技術不一樣,因此不同的編碼系統會造成這個欄位的長度不相同。 舉例來說,舊式的 DES 編碼系統產生的密碼長度就與目前慣用的 MD5 不同(註2)!MD5 的密碼長度明顯的比較長些。由於固定的編碼系統產生的密碼長度必須一致,因此『當你讓這個欄位的長度改變後,該密碼就會失效(算不出來)』。 很多軟體透過這個功能,在此欄位前加上 ! 或 * 改變密碼欄位長度,就會讓密碼『暫時失效』了。
  3. 最近更動密碼的日期
    這個欄位記錄了『更動密碼那一天』的日期,不過,很奇怪呀!在我的例子中怎麼會是 14126 呢?呵呵,這個是因為計算 Linux 日期的時間是以 1970 年 1 月 1 日作為 1 而累加的日期,1971 年 1 月 1 日則為 366 啦! 得注意一下這個資料呦!上述的 14126 指的就是 2008-09-04 那一天啦!瞭解乎? 而想要瞭解該日期可以使用本章後面 chage 指令的幫忙!至於想要知道某個日期的累積日數, 可使用如下的程式計算:

    上述指令中,2008/09/04 為你想要計算的日期,86400 為每一天的秒數, %s 為 1970/01/01 以來的累積總秒數。 由於 bash 僅支援整數,因此最終需要加上 1 補齊 1970/01/01 當天。

  4. 密碼不可被更動的天數:(與第 3 欄位相比)
    第四個欄位記錄了:這個帳號的密碼在最近一次被更改後需要經過幾天才可以再被變更!如果是 0 的話, 表示密碼隨時可以更動的意思。這的限制是為了怕密碼被某些人一改再改而設計的!如果設定為 20 天的話,那麼當你設定了密碼之後, 20 天之內都無法改變這個密碼呦!
  5. 密碼需要重新變更的天數:(與第 3 欄位相比)
    經常變更密碼是個好習慣!為了強制要求使用者變更密碼,這個欄位可以指定在最近一次更改密碼後, 在多少天數內需要再次的變更密碼才行。你必須要在這個天數內重新設定你的密碼,否則這個帳號的密碼將會『變為過期特性』。 而如果像上面的 99999 (計算為 273 年) 的話,那就表示,呵呵,密碼的變更沒有強制性之意。
  6. 密碼需要變更期限前的警告天數:(與第 5 欄位相比)
    當帳號的密碼有效期限快要到的時候 (第 5 欄位),系統會依據這個欄位的設定,發出『警告』言論給這個帳號,提醒他『再過 n 天你的密碼就要過期了,請盡快重新設定你的密碼呦!』,如上面的例子,則是密碼到期之前的 7 天之內,系統會警告該用戶。
  7. 密碼過期後的帳號寬限時間(密碼失效日):(與第 5 欄位相比)
    密碼有效日期為『更新日期(第3欄位)』+『重新變更日期(第5欄位)』,過了該期限後使用者依舊沒有更新密碼,那該密碼就算過期了。 雖然密碼過期但是該帳號還是可以用來進行其他工作的,包括登入系統取得 bash 。不過如果密碼過期了, 那當你登入系統時,系統會強制要求你必須要重新設定密碼才能登入繼續使用喔,這就是密碼過期特性。那這個欄位的功能是什麼呢?是在密碼過期幾天後,如果使用者還是沒有登入更改密碼,那麼這個帳號的密碼將會『失效』, 亦即該帳號再也無法使用該密碼登入了。要注意密碼過期與密碼失效並不相同
  8. 帳號失效日期
    這個日期跟第三個欄位一樣,都是使用 1970 年以來的總日數設定。這個欄位表示: 這個帳號在此欄位規定的日期之後,將無法再使用。 就是所謂的『帳號失效』,此時不論你的密碼是否有過期,這個『帳號』都不能再被使用! 這個欄位會被使用通常應該是在『收費服務』的系統中,你可以規定一個日期讓該帳號不能再使用啦!
  9. 保留
    最後一個欄位是保留的,看以後有沒有新功能加入。

Tips:

假如忘记了普通用户的密码,可以直接使用root账户修改:

假如忘记了root的密码,就需要进入单用户模式进行修改,

单模式请看链接:http://bananalighter.com/linux-single-user-change-password/

 

未完续不下去了。。。性价比有点低,自己默默看

好长:http://linux.vbird.org/linux_basic/0410accountmanager.php#account_id

 

 

Linux的inode的理解

原文:http://www.cnblogs.com/itech/archive/2012/05/15/2502284.html

一、inode是什么?

理解inode,要从文件储存说起。
文件储存在硬盘上,硬盘的最小存储单位叫做”扇区”(Sector)。每个扇区储存512字节(相当于0.5KB)。

 

操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个”块”(block)。这种由多个扇区组成的”块”,是文件存取的最小单位。”块”的大小,最常见的是4KB,即连续八个 sector组成一个 block。

 

文件数据都储存在”块”中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为”索引节点”。

 

二、inode的内容
inode包含文件的元信息,具体来说有以下内容:
  * 文件的字节数
  * 文件拥有者的User ID
  * 文件的Group ID
  * 文件的读、写、执行权限
  * 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
  * 链接数,即有多少文件名指向这个inode
  * 文件数据block的位置

 

可以用stat命令,查看某个文件的inode信息:
stat example.txt
总之,除了文件名以外的所有文件信息,都存在inode之中。至于为什么没有文件名,下文会有详细解释。

 

三、inode的大小
inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。
每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。

 

查看每个硬盘分区的inode总数和已经使用的数量,可以使用df命令。
df -i
查看每个inode节点的大小,可以用如下命令:
sudo dumpe2fs -h /dev/hda | grep “Inode size”
由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。

 

四、inode号码
每个inode都有一个号码,操作系统用inode号码来识别不同的文件。

 

这里值得重复一遍,Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。

使用ls -i命令,可以看到文件名对应的inode号码:

ls -i example.txt

 

五、目录文件
Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。

 

目录文件的结构非常简单,就是一系列目录项(dirent)的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。

 

ls命令只列出目录文件中的所有文件名:
ls /etc
ls -i命令列出整个目录文件,即文件名和inode号码:
ls -i /etc
如果要查看文件的详细信息,就必须根据inode号码,访问inode节点,读取信息。ls -l命令列出文件的详细信息。
ls -l /etc

 

六、硬链接
一般情况下,文件名和inode号码是”一一对应”关系,每个inode号码对应一个文件名。但是,Unix/Linux系统允许,多个文件名指向同一个inode号码。这意味着,可以用不同的文件名访问同样的内容;对文件内容进行修改,会影响到所有文件名;但是,删除一个文件名,不影响另一个文件名的访问。这种情况就被称为”硬链接”(hard link)。

ln命令可以创建硬链接:

ln 源文件 目标文件
运行上面这条命令以后,源文件与目标文件的inode号码相同,都指向同一个inode。inode信息中有一项叫做”链接数”,记录指向该inode的文件名总数,这时就会增加1。反过来,删除一个文件名,就会使得inode节点中的”链接数”减1。当这个值减到0,表明没有文件名指向这个inode,系统就会回收这个inode号码,以及其所对应block区域。

 

这里顺便说一下目录文件的”链接数”。创建目录时,默认会生成两个目录项:”.”和”..”。前者的inode号码就是当前目录的inode号码,等同于当前目录的”硬链接”;后者的inode号码就是当前目录的父目录的inode号码,等同于父目录的”硬链接”。所以,任何一个目录的”硬链接”总数,总是等于2加上它的子目录总数(含隐藏目录),这里的2是父目录对其的“硬链接”和当前目录下的”.硬链接“。

 

七、软链接
除了硬链接以外,还有一种特殊情况。文件A和文件B的inode号码虽然不一样,但是文件A的内容是文件B的路径。读取文件A时,系统会自动将访问者导向文件B。因此,无论打开哪一个文件,最终读取的都是文件B。这时,文件A就称为文件B的”软链接”(soft link)或者”符号链接(symbolic link)。

 

这意味着,文件A依赖于文件B而存在,如果删除了文件B,打开文件A就会报错:”No such file or directory”。这是软链接与硬链接最大的不同:文件A指向文件B的文件名,而不是文件B的inode号码,文件B的inode”链接数”不会因此发生变化。

 

ln -s命令可以创建软链接。
ln -s 源文文件或目录 目标文件或目录

 

八、inode的特殊作用
由于inode号码与文件名分离,这种机制导致了一些Unix/Linux系统特有的现象。
  1. 有时,文件名包含特殊字符,无法正常删除。这时,直接删除inode节点,就能起到删除文件的作用。
  2. 移动文件或重命名文件,只是改变文件名,不影响inode号码。
  3. 打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名。因此,通常来说,系统无法从inode号码得知文件名。
      第3点使得软件更新变得简单,可以在不关闭软件的情况下进行更新,不需要重启。因为系统通过inode号码,识别运行中的文件,不通过文件名。更新的时候,新版文件以同样的文件名,生成一个新的inode,不会影响到运行中的文件。等到下一次运行这个软件的时候,文件名就自动指向新版文件,旧版文件的inode则被回收。

 

九 实际问题

在一台配置较低的Linux服务器(内存、硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命令查看了一下磁盘使用情况,发现/data分区只使用了66%,还有12G的剩余空间,按理说不会出现这种问题。 后来用df -i查看了一下/data分区的索引节点(inode),发现已经用满(IUsed=100%),导致系统无法创建新目录和文件。

 

 

查找原因:

/data/cache目录中存在数量非常多的小字节缓存文件,占用的Block不多,但是占用了大量的inode。

 

解决方案:
1、删除/data/cache目录中的部分文件,释放出/data分区的一部分inode。
2、用软连接将空闲分区/opt中的newcache目录连接到/data/cache,使用/opt分区的inode来缓解/data分区inode不足的问题:
ln -s /opt/newcache /data/cache

 

 

 

【翻译】HBase 集群安装与配置

单机模式安装、启动 HBase

安装 HBase Master

安装HBase Master

 启动HBase Master服务

安装及启动HBase Thrift Server

安装HBase Thrift Server

启动HBase Thrift Server

安装配置HBase REST

安装HBase REST

配置REST端口(如果采用默认的60050则不需配置)

修改hbase-site.xml

启动HBase REST

安装至此,即可单机享用HBase。

HBase分布式安装配置

集群机器规划

按照以下规划安装对应的软件包

Node Name Master ZooKeeper RegionServer

hadoop01

yes

yes

no

hadoop02

backup

yes

yes

hadoop03

no

yes

yes

安装软件包命令

master

 region server

准备hadoop01

配置region server

编辑/etc/hbase/conf/regionservers,添加hadoop02、03.

配置hadoop02为backup master

新增文件/etc/hbase/conf/backup-masters,添加一行hadoop02

配置HBase为分布式模式

编辑/etc/hbase/conf/hbase-site.xml

配置zookeeper

/etc/hbase/conf/hbase-site.xml添加参数

其中dataDir参数参考本机的/etc/zookeeper/conf/zoo.cfg

在HDFS上创建/hbase目录

配置hadoop02、03

拷贝hadoop01配置文件到02、03

分别启动服务

在hadoop01、02启动hbase-master

在hadoop02、03启动hbase-regionserver

检查服务状态

在各服务器执行:jps

hadoop01:

hadoop02:

hadoop03:

参考

单机模式安装、启动 HBase:http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/cdh_ig_hbase_standalone_start.html

HBase分布式安装配置:http://hbase.apache.org/book.html#_introduction

HBase分布式安装配置(伪分布式):

http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/cdh_ig_hbase_pseudo_configure.html

 HBase分布式安装配置(伪分布式->集群):

http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/cdh_ig_hbase_cluster_deploy.html

 

【翻译】hbase installation

原文:(安装)http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/cdh_ig_hbase_install.html

(BlockCache)http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/admin_hbase_blockcache_configure.html

Installing HBase(安装Hbase)

配置HBase(Configuration Settings for HBase)

使用hdfs的线程数参数(Using dfs.datanode.max.transfer.threads with HBase)

HDFS datanode有最大伺服文件数限制。该上限由dfs.datanode.max.transfer.threads参数控制。在加载HBase之前,确认已经在$HADOOP_HOME/conf/hdfs-site.xml文件中配置了该参数:

将配置文件发送到集群,并重启HDFS以生效。

否则会报与block相关的奇怪错误。

配置HBase的BlockCache(Configuring the HBase BlockCache)

扩展阅读:

堆内存与堆外内存:http://bananalighter.com/java-off-heap-on-heap/

块缓存1:http://www.cnblogs.com/panfeng412/archive/2012/09/24/hbase-block-cache-mechanism.html

块缓存2:http://punishzhou.iteye.com/blog/1277141

HBase提供了堆内存及堆外内存两种块缓存的实现。

堆内存:默认的堆内存块缓存实现是LruBlockCache(java)。桶缓存可以用堆内存,也可以用堆外内存。

结合:如果操作的数据超出堆容量,可以使用桶缓存作为堆内存LruBlockCache的二级缓存(L2 cache)。这个实现在CombinedBlockCache中有涉及。

 

 

 

 

 

 

 

 

 

堆外内存(off-heap),堆内存(on-heap)

原文:http://www.infoq.com/cn/news/2014/12/external-memory-heap-memory/

一般情况下,Java中分配的非空对象都是由Java虚拟机的垃圾收集器管理的,也称为堆内内存(on-heap memory)。虚拟机会定期对垃圾内存进行回收,在某些特定的时间点,它会进行一次彻底的回收(full gc)。彻底回收时,垃圾收集器会对所有分配的堆内内存进行完整的扫描,这意味着一个重要的事实——这样一次垃圾收集对Java应用造成的影响,跟堆的大小是成正比的。过大的堆会影响Java应用的性能。

对于这个问题,一种解决方案就是使用堆外内存(off-heap memory)。堆外内存意味着把内存对象分配在Java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机)。这样做的结果就是能保持一个较小的堆,以减少垃圾收集对应用的影响。

但是Java本身也在不断对堆内内存的实现方式做改进。两者各有什么优缺点?Vanilla Java博客作者Peter Lawrey撰写了一篇文章,在文中他对三种方式:用new来分配对象、对象池(object pool)和堆外内存,进行了详细的分析。

用new来分配对象内存是最基本的一种方式,Lawery提到:

在Java 5.0之前,分配对象的代价很大,以至于大家都使用内存池。但是从5.0开始,对象分配和垃圾回收变得快多了,研发人员发现了性能的提升,纷纷简化他们的代码,不再使用内存池,而直接用new来分配对象。从5.0开始,只有一些分配代价较大的对象,比如线程、套接字和数据库链接,用内存池才会有明显的性能提升。

对于内存池,Lawery认为它主要用于两类对象。第一类是生命周期较短,且结构简单的对象,在内存池中重复利用这些对象能增加CPU缓存的命中率,从而提高性能。第二种情况是加载含有大量重复对象的大片数据,此时使用内存池能减少垃圾回收的时间。对此,Lawery还以StringInterner为例进行了说明。

最后Lawery分析了堆外内存,它和内存池一样,也能缩短垃圾回收时间,但是它适用的对象和内存池完全相反。内存池往往适用于生命期较短的可变对象,而生命期中等或较长的对象,正是堆外内存要解决的。堆外内存有以下特点:

  • 对于大内存有良好的伸缩性
  • 对垃圾回收停顿的改善可以明显感觉到
  • 在进程间可以共享,减少虚拟机间的复制

Lawery还提到对外内存最重要的还不是它能改进性能,而是它的确定性。

当然堆外内存也有它自己的问题,最大的问题就是你的数据结构变得不那么直观,如果数据结构比较复杂,就要对它进行串行化(serialization),而串行化本身也会影响性能。另一个问题是由于你可以使用更大的内存,你可能开始担心虚拟内存(即硬盘)的速度对你的影响了。

Lawery还介绍了OpenHFT公司提供三个开源库:Chronicle QueueChronicle MapThread Affinity,这些库可以帮助开发人员使用堆外内存来保存数据。采用堆外内存有很多好处,同时也带来挑战,对堆外内存感兴趣的读者可以阅读Lawery的原文来了解更多信息。

CentOS 修改字符集

查看可用字符集

修改

 查看当前字符集

 

 

list