少女时代(Girls' Generation)是韩国著名的女子流行演唱组合,由金泰妍、郑秀妍、李顺圭、黄美英、金孝渊、权侑莉、崔秀英、林允儿、徐珠贤9名成员组成。
2007年8月初凭借首个团综《少女上学去》和出道单曲《再次重逢的世界》开始进入大家的视野,并迅速走红。其后更凭借《Gee》《Genie》《Oh!》《Hoot》等多首热门歌曲风靡大街小巷。2010年9月以一首《GENIE》进军日本乐坛。2011年10月中旬又以一首《The Boys》进军美国乐坛。
自出道以来,少女时代就以优异的成绩改写了韩国女子组合乐坛在历史上的强大气势,并在中国、日本、泰国等亚洲国家和欧美等国家都累积出一定的知名度。她们除了作为歌手外,还以电视剧和音乐剧演员、电台DJ、节目MC和平面模特等身份活跃在演艺圈其他领域。曾连续两年被选入韩国福布斯名人榜首位,在韩国乃至亚洲都拥有着超高的人气。
艺名:Taeyeon(泰妍,港台翻译为"太妍")[1]
本名:金泰妍(韩国身份证上的汉字为"金泰耎")
韩文名:김태연(Kim Tae Yeon)
日文称呼:キムテヨン
金泰妍
所属组合:少女时代
队内职务:队长、主唱、高音担当
出生地:全罗北道全州市
身高:158cm(官网)
体重:45kg
生肖:蛇
血型:O型
幸运数字:9(在Oh!里说的,因为生日是3月9日。也因为少女时代是9个少女的整体)
性格:可爱、搞笑、抽风、率真、爽朗、认真
绰号:taenggu(韩饭爱称)、抽抽、抽队、小队、小抽、金小抽、daedae(家人成员使用)、果达(自称,削苹果达人)、果冻(在我们结婚了中的爱称)、泰花(rain起的)、变态妍、万年童颜、泰妍妈妈、taeng DJ、小白熊、小鬼队长、短身(秀英起的)、萌神、金爷、金软软(性格很好,中饭爱称)、Taeng9、小王纸(日巡RDR造型)糖球
家庭成员:爸爸、妈妈、哥哥(金志雄,和泰妍长得很像)、妹妹(金夏妍)
学历:全州艺术高等学校(放送文化艺术科 3年级, 2008年2月5日毕业, 获功劳奖)
首尔清潭高等学校(人文科, 2005年 ~ 2007年)
全州扬志中学(2002年 ~ 2005年)
全州新星小学(1996年 ~ 2002年)
语言:韩语、中文(少许、曾来过中国)、日语(为了在日本的活动,努力学习日语)
习惯:做的事情要记下来、爱唠叨
座右铭:不要做让自己后悔的事
特长:唱歌、贝斯、吉他、摩托艇、潜泳、学习作曲
喜欢的天气:刮风下雨的天气
喜欢的动物:小狗、兔子
喜欢的植物:粉玫瑰
喜欢的季节:夏季
喜欢的科目:体育
喜欢的饮品:黑豆豆奶、牛奶
喜欢的异性类型:积极、有幽默感、有融通性、皮肤好、有宽宽的肩膀、腰细
喜欢的水果:橘子、苹果、柠檬
喜欢的蔬菜:西红柿
喜欢的男艺人:姜东元
喜欢的歌手:宝儿(BoA)
出道前老师:The One
喜欢的数字:9
喜欢的食物:韩国料理
喜欢的**:《马拉松》《惊天夺宝》
喜欢的花:粉色玫瑰
喜欢的颜色:粉红色
最宝贝的东西:手机(经常在机场看到泰妍拿着手机)
经纪公司:SMEntertainment
消除紧张的方法:想些别的事,听音乐转移心情
练习生时长:3年零4个月(SM Star Light Academy 声乐科4期 练习生)
室友:Tiffany、张力尹、f(x)崔雪莉(未出道前)
允儿、秀英(从出道至2009年7月)
Sunny(2009年7月以后)
Tiffany、Sunny(日本宿舍)
练习生时间:7年零6个月(少女时代里练习时间最长的)
座右铭:Follow my heart
郑秀妍
幸运数字:22
外号:西卡、郑西卡、兵长Ssica、小金毛、冰山女王、金发尤物、懵萌、睡美人、睡公主、郑JESSICA JESSI、JC(这三个都是帕尼所取);章鱼头(允儿所取)、菜刀(希澈所取),sicca, 小金毛、桶西卡、囧毛、树袋熊、毛毛、初恋xi(因出演《暴力罗曼史》而得名)等
家庭成员:父母,妹妹 (f(x)组合成员Krystal[1]郑秀晶)
语言:韩语、英语、中文(少许)、日语(正在学习中)
室友:孝渊(出道至09年7月)、秀英(09年7月至今)
学历:Korea Kent Foreign School
爱好:看**
专长:睡觉、英语、钢琴、唱歌、跳舞 、架子鼓、芭蕾、足球、拳击
最讨厌的东西:黄瓜、西瓜、南瓜
性格:特别爱害羞、好坏分明、直爽、四次元,有时冷冰冰(但也很善良)
经常待的地方:运动房、家里的床
喜欢的男艺人:丹尼尔·亨利(演员)
喜欢的女艺人:BoA
喜欢的**:《罗密欧与朱丽叶》
喜欢的天气:晴天
喜欢的食物:冰淇淋
喜欢的季节:春天
喜欢的颜色:粉红色
最喜欢做的动作:包子脸
耿耿于怀的事情:自己的宽额头
座右铭:Follow My Heart
喜欢的歌曲:《Love Me In A Special Way》
喜欢的游戏:没有(不喜欢游戏)
手机画面上的字幕:爱心桃
一天发短信的次数:每天都有不同
自己拥有的香水:ANNA SUI DREAM
一个月的零花钱:需要的时候要
理想型:个子高,肩膀宽,像大人样,有点罗曼史感觉并且像个男人,手漂亮
爱情VS友情:两个都很重要
我爱的人VS爱我的人:爱我的人我也爱他,我爱的人也爱我的时候最幸福不过了
最想爱人的时候:写日记的时候
看异性的时候最挑剔的部位:手,眼睛
爱情是:用语言表达不了
记忆里最深刻的梦:做完梦就忘尊敬的人:OriBeahotse
常去的地方:咖啡厅
爱穿衣服的类型:abercrombie,Sevenby
艺名:Sunny (港台翻译为"姗妮")
sunny
本名:李顺圭
韩文名:이순규(Lee Soon Gyu)
日文称呼:ソニ(イスンギュ)
队内职务:第五主唱、活力素担当、撒娇担当
生日:1989年5月15日
星座:金牛座
身高:158cm(出道:155cm)
体重:45kg(出道:42kg)
家庭:父母,姐姐(李珍圭、李银圭,二姐担任过Sugar组合所属公司的代表,分别大Sunny10岁,15岁)
爸爸:李洙英(李秀满的亲哥哥、担任过Sugar组合所属公司的代表)
叔叔:李秀满(SM公司理事)
血型:B型
喜欢的颜色 :粉红色
座右铭:Everyday Sunny Day!
爱好:招拳头撒娇 跳舞 唱歌读书,运动,打游戏。
性格:有令人惊叹的艺能感(连gagman都羡慕的),有亲切感,很温暖的人
皮肤:讨人喜欢的白皙
喜欢看的书类型:爱情小说
喜欢的食物:面包
学历:培化女子高中毕业
加入SM经历:07年SM Casting System(先前在别的公司训练5年,并且又准备出道4年,所以说她总共训练了9年!07年由Sugar组合亚由美前辈推荐参加SM甄选,凭藉帅气惊人的表演获得认可)
室友:Yuri(出道至09年7月)、泰妍(09年7月至今)
昵称:小太阳、活力素(出道时期官方称号)、顺圭、假幺、三郎(9只中生日排行第三)、抓鸡专业户(出自青春不败)
圈中好友:少女时代成员、Super Junior组合成员、SHINee组合成员、f(x)组合成员、青春不败G7成员、青春不败2G8成员等。
Instagram ID:svnnynight[1]
中文个站:百度李顺圭吧[2]、OUR LOVE SUNNY[3]、李顺圭台湾首站[4]
蒂芬妮
艺名:Tiffany(帕尼,港台翻译为"蒂芬妮")
本名:黄美英
英文名:Stephanie Hwang(因为韩国演艺圈早有组合天上智喜的成员金宝京艺名为Stephanie,遂以她母亲一开始给她取的名字Tiffany作为艺名出道)
韩文名:티파니(tiffany)本名:黄美英 황미영(Hwang Mi Young)
日文名:ファンミヨウン
昵称:蘑菇T(出道初期,老把“比宝石还闪亮的Tiffany”说成“比蘑菇还闪亮的Tiffany”),黄秘书(由于看电视的时候不小心换错台,预订了午夜档的《女秘书》而得名),帕尼(艺名的谐音)、傻T(总是傻傻的)、错ffany、Diffany(总是跳错舞步,其实跳错最多的不是她,而是另有其人,只是她跳错的部分总被摄影机拍到)、角落ffany(出道时跳舞总被安排在角落)、笑眼T(因为她的笑容比钻石还要闪亮,还有是小T的谐音),米勇(原名韩文发音的谐音),一姐(源于在机场带着黑墨镜霸气外露)
星座:狮子座
身高:163CM
体重:48KG
血型:O型
队内职务:主唱、部分领言、笑眼担当
粉丝名:TiffoliC
宗教:基督教
幸运数字:07
语言:英语、韩语
特长:长笛、芭蕾 、英文、拉拉队队员(帕尼在美国的小学初中和韩国的国际学校里都是拉拉队队员)
出生地:美国加利福尼亚州旧金山(和郑秀妍同一家医院出生[1]) 于洛杉矶长大
家庭成员:爸爸、妈妈(小T的妈妈在02年时去世了)、姐姐(Michelle就读于伯克利大学)、哥哥(Leo)、狗狗(罗密欧) 宠物:狗狗(罗密欧、杰克逊·黄)
喜欢的颜色:粉红(完全疯狂的喜欢)
喜欢的艺人:BoA
喜欢的吃饭习惯:吃东西前把食物切成一个个小块
座右铭:Just work hard(Practice makes Perfect), Today is my day
喜欢的珠宝品牌:Tiffany & Co
练习生时间:三年零七个月
室友:徐贤(出道至09年7月)、现无(因为行李很多,所以搬新家以后就让她单独住一个单间)
经纪公司:SMEntertainment
加入SM Ent:2004年SM Casting System(CJ/KMTV USA-LA Contest第一名)
学历:初中——South Pointe(美国)高中——Diamond Bar High School(美国)Korea Kent Foreign School(韩国)高中-Diamond Bar High School (美国)
金孝渊
艺名:Hyoyeon(孝渊,港台翻译为“孝妍”)
本名:金孝渊
韩文名:김효연(Kim Hyo Yeon)
日文称呼:キムヒョヨン
昵称:渊宝、舞后、DQ、金小学生、金十岁、金初丁、女版Rain、Sexygirl、口误兄妹(with 金元俊)、渊美人、小渊、Baby渊、国民初丁、孝作家、金小朋友、孝美(青春不败2)、rapper渊、韩国布兰妮(神话放送)、时装恐怖分子(秀英称)、俄罗斯姨妈(青春不败2)、女版MJ、孝昂丝(Brain称)
队内职务:主领舞、副主唱、舞蹈担当、中文担当、搞笑担当、欧美人气担当
生日:1989年9月22日
星座:处女座
身高:160cm
体重:43kg
血型:AB型
出生地:京畿道仁川广域市
家人:父母
语言:韩语,汉语,英语(基础语句),日语(基础语句),泰语(基础语句)
专长:舞蹈、唱歌、中文(曾经来中国北京留学)
舞学:Hip-pop、拉丁、芭蕾、Popin (Locking)、Jazz、踢踏、探戈、恰恰等
所属团队:少女时代、SM公司特别跨团小组Younique Unit
所属公司:SM Entertainment
出道日期: 2007年8月5日
练习生时间:六年零一个月
教舞老师:Justin,Janet Jackson, 沈在元
室友:郑秀妍(出道至09年7月)、徐贤(09年7月至今)
喜欢的男艺人:木村拓哉、金圭钟
喜欢的女艺人:李孝利
喜欢的料理:拌饭、炒年糕
尊敬的人:父母、朴成真(音译)团长、李秀满老师
最擅长的体育运动:有氧慢跑
觉得自己最帅的时候:认真跳舞的时候
座右铭:Everyone that works hard will succeed
喜欢的数字:2、3
喜欢的颜色:粉红色
自己的优点:有礼貌、性格率真开朗
食量:吃多的话一天7-8顿,吃少的话一天1顿
拿手菜:寿司、咖喱紫菜包饭炒饭(在happy together3和允儿共同完成)
向往的旅游胜地:夏威夷、关岛
喜欢看的电视节目:X-MAN
最疼的时候:骨髓弄出来的时候
感受到幸福的时候:吃饭的时候、购物的时候、练舞的时候
生气的时候你做什么动作:什么都不做,没表情,很安静
不能吃的东西:鱼汤、鱼子酱
喜欢的水果:桃子、草莓
喜欢的季节:夏天
看异性的顺序:先外表后性格
被异性说的最多的话:美丽、魅力舞后、非常有魅力(柳熙烈在节目中称赞)
害怕的东西:突如其来的烟花和礼炮
理想型:幽默且和孝渊有共同爱好的人,喜欢运动,五官清晰的人
圈内好友 :少女时代成员,SHINee成员 ,Super Junior成员,刘宪华(SJ-M),F(x)成员,李钟硕,姜智英 、郑妮可(KARA),朴素妍(T-ARA)金艺媛(jewelry),尹宝拉(Sistar),裴秀智、 李玟暎(miss A),黄光熙(ZE:A),金钟仁、鹿晗、张艺兴(EXO),Sririta Jensen(泰国女星),Brain,吴尚镇等
权侑莉(Yuri)
韩国著名女子团体少女时代成员,队里的领舞之一。文静秀气的外表,健康的身型,完美展现出可爱又性感的双重感觉。年幼梦想成为演员的她,在2001年获得第一届SMEntertainment青少年最佳选拔赛“最佳舞蹈本赏”,其后经过6年训练,2007年8月以少女时代组合出道。凭借出色的个人能力与个人魅力,成功走上多元化发展道路。在演艺界里,她以独特的幽默感与亲和力,带来“艺能Yul”的称号,同时长期担任《MBC音乐中心》主持人,多次主持年末庆典与演唱会。2012年首次以演员身份参演了《时尚王》,并凭借该剧斩获当年的SBS演技大赏新星赏与百想艺术大赏TV部女子人气赏,其发展潜力也为业界所看好。目前,Yuri正投入**《No Breathing》拍摄中,有望于下半年首秀大荧幕。
中文名:崔秀英
外文名:최수영(Choi Soo Young)
别名:Sooyoung,秀英
国籍:韩国
民族:朝鲜族
星座:水瓶座
血型:O型
身高:170cm
体重:48kg
出生地:韩国京畿道光州市
出生日期:1990年2月10日
职业:歌手、演员、主持人
毕业院校:韩国中央大学演艺演技科(09级)
经纪公司:SMEntertainment
代表作品:再次重逢的世界,Gee,Genie,Oh!,The Boys,I Got A Boy
所属团队:少女时代
队内职务:副主唱,领舞
影视作品:第三医院、恋爱操作团:Cyrano
林允儿(Yoona)
韩国著名女子团体少女时代成员,队里的领舞之一,拥有甜美的外表和活泼的性格,因此担任"少女时代"的门面。2002年被韩国SMEntertainment公司发掘当练习生,出道前就曾接拍过广告和参演电视剧亦被观众熟知,是少女时代演艺经历较为丰富的成员之一。2007年8月5日以少女时代组合正式出道,除了当歌手外,个人也主演了《你是我的命运》《辛德瑞拉先生》《爱情雨》等热门电视剧且屡屡获奖,演技颇受好评。2013年8月被韩国媒体评选为亚洲地区最美女星第一名[1];近期将参演《总理和我》,并担任女主角
徐珠贤
艺名:Seohyun(港台翻译为"徐玄")
本名:徐珠贤(韩国身份证上的汉字为"徐朱玄")
韩文名:서주현(Seo Ju Hyun)
日文称呼:ソヒョン
队内职务:主唱、领舞
生日:1991年6月28日
星座:巨蟹座
身高:168cm
体重:48kg
血型:A
家庭成员:妈妈 爸爸
幸运数字:6
喜欢的数字:1(在100222 SBS FM甜蜜与苦涩的ten 俱乐部里提到)
专长:钢琴、吉他
学历:大永高中(高一高二), 全州艺术高中(高三),东国大学戏剧**系(2010级)
喜欢的颜色:粉红色(《我们结婚了》中提及)
喜欢的动画:Keroro(没有看,但会听一下音乐回忆一下——《至亲笔记》里提到)
喜欢的动漫人物:Keroro军曹
喜欢的食物:红薯(地瓜)
喜欢的水果:西瓜、柿子
喜欢的电视剧:交响情人梦
喜欢的**:加勒比海盗
擅长的语言:韩语、英语、日语、汉语
偶像:潘基文(现任联合国秘书长)(在《我们结婚了》提及)
喜欢的男艺人:刘在石、约翰尼·德普
喜欢的偶像:CNBLUE
喜欢的书:自我开发类的(在《我们结婚了》中提及)
理想:30年后希望能成为一名外交官(乘风破浪EP11提及)
加入SM ENT:SM 地铁 Casting System(2003)(03年乘坐地铁时被SM发掘 071101电台节目《李言和金申英的深深打破》有提及)
练习生时间:四年零六个月
室友:Tiffany(出道至09年7月)、孝渊(09年7月至今)
圈内好友:少女时代成员 、SHINee成员、KARA(郑妮可、姜智英)、2AM(珍云)CNblue成员等
昵称:老小、忙内(韩语中“老幺的发音”)、小贤贤、SeoRoro、受气包、徐小贤、小9、SeoBaby
少女时代里面倍受疼爱的乖巧老小。是个爱学习爱养生的认真孩子,中文发音标准的像播音员般甜美而字正腔圆。因为妈妈是钢琴学校的校长,所以徐珠贤弹得一手好钢琴。拥有清脆稳定的声线,在现场里发挥也很稳定,年纪虽小但一点也不怯场,所以得到了不少哥哥姐姐甚至大叔级Fans的喜爱。还在念高中的徐珠贤喜欢青蛙Keroro军曹,平时也追看日剧,亲切得就像是邻家的妹妹一样,鼓鼓的脸蛋真想上去捏捏,标准的“葫芦”身材,给人性感的味道。少女时代的徐珠贤,如纯洁无瑕的天使一般,就是个单纯乖巧犹如棉花糖的宝贝,长得跟娃娃一样可爱,惹人喜爱,同时也一个善良安静的少女。
队内王道公式官配CP :允贤(林允儿+徐珠贤)
都是按顺序来的~
天下城市星座小区地址:江汉区菱角湖路2号。
周边直线1KM范围内交通配套资源有(菱角湖,三眼桥,取水楼,长江日报路新华路口,天门敦路香江新村,长江日报路地铁菱角湖站,天门墩路香江新村,菱角湖路省新华医院,台北路天门墩,新华路马场角,长江日报路长江日报,新华路北湖,香港路紫藤花园)等。
直线2KM范围内教育资源有10个(秦汉书院,新东方(江岸台北一路校区),江汉区劳动就业培训中心-服务员实训基地,三山驾校(天门墩路),尖子生教育,优胜教育,环境宣传教育中心,建安驾校,艺沙星教育,钦点金榜教育)等。
周边2KM医疗资源有6个,其中湖北省脑科中心距离小区123米,湖北省中西医结合医院距离小区306米,武汉市红十字会医院距离小区1011米,中医院(台北分院)距离小区1178米,长江航运总医院距离小区1282米,武汉市第六医院距离小区1693米,为医疗需求提供保障。
天下城市星座周边商业配套有:(克瑞着色纹发中心,果唯伊(菱角湖壹号店),Combo书店,景初珠宝·JC Jewelry,壹号天地,中百超市(北湖晶立方店),亮亮超市(菱角湖路店),中百仓储(北湖购物广场店),中百超市(凤凰城店),沃尔玛购物广场(万达广场店))等。
更多:天下城市星座小区详细信息
这篇文章将首先介绍一些所需的基本知识,如操作系统对进程的内存管理以及相关的系统调用,然后逐步实现一个简单的malloc。为了简单起见,这篇文章将只考虑x86_64体系结构,操作系统为Linux。
1 什么是malloc
2 预备知识
221 内存排布
222 Heap内存模型
223 brk与sbrk
224 资源限制与rlimit
211 虚拟内存地址与物理内存地址
212 页与地址构成
213 内存页与磁盘页
21 Linux内存管理
22 Linux进程级内存管理
3 实现malloc
321 数据结构
322 寻找合适的block
323 开辟新的block
324 分裂block
325 malloc的实现
326 calloc的实现
327 free的实现
328 realloc的实现
31 玩具实现
32 正式实现
33 遗留问题和优化
4 其它参考
1 什么是malloc
在实现malloc之前,先要相对正式地对malloc做一个定义。
根据标准C库函数的定义,malloc具有如下原型:
void malloc(size_t size);
这个函数要实现的功能是在系统中分配一段连续的可用的内存,具体有如下要求:
malloc分配的内存大小至少为size参数所指定的字节数
malloc的返回值是一个指针,指向一段可用内存的起始地址
多次调用malloc所分配的地址不能有重叠部分,除非某次malloc所分配的地址被释放掉
malloc应该尽快完成内存分配并返回(不能使用NP-hard的内存分配算法)
实现malloc时应同时实现内存大小调整和内存释放函数(即realloc和free)
对于malloc更多的说明可以在命令行中键入以下命令查看:
man malloc
2 预备知识
在实现malloc之前,需要先解释一些Linux系统内存相关的知识。
21 Linux内存管理
211 虚拟内存地址与物理内存地址
为了简单,现代操作系统在处理内存地址时,普遍采用虚拟内存地址技术。即在汇编程序(或机器语言)层面,当涉及内存地址时,都是使用虚拟内存地址。采用这种技术时,每个进程仿佛自己独享一片2N
字节的内存,其中N是机器位数。例如在64位CPU和64位操作系统下,每个进程的虚拟地址空间为264
Byte。
这种虚拟地址空间的作用主要是简化程序的编写及方便操作系统对进程间内存的隔离管理,真实中的进程不太可能(也用不到)如此大的内存空间,实际能用到的内存取决于物理内存大小。
由于在机器语言层面都是采用虚拟地址,当实际的机器码程序涉及到内存操作时,需要根据当前进程运行的实际上下文将虚拟地址转换为物理内存地址,才能实现对真实内存数据的操作。这个转换一般由一个叫MMU(Memory Management Unit)的硬件完成。
212 页与地址构成
在现代操作系统中,不论是虚拟内存还是物理内存,都不是以字节为单位进行管理的,而是以页(Page)为单位。一个内存页是一段固定大小的连续内存地址的总称,具体到Linux中,典型的内存页大小为4096Byte(4K)。
所以内存地址可以分为页号和页内偏移量。下面以64位机器,4G物理内存,4K页大小为例,虚拟内存地址和物理内存地址的组成如下:
上面是虚拟内存地址,下面是物理内存地址。由于页大小都是4K,所以页内便宜都是用低12位表示,而剩下的高地址表示页号。
MMU映射单位并不是字节,而是页,这个映射通过查一个常驻内存的数据结构页表来实现。现在计算机具体的内存地址映射比较复杂,为了加快速度会引入一系列缓存和优化,例如TLB等机制。下面给出一个经过简化的内存地址翻译示意图,虽然经过了简化,但是基本原理与现代计算机真实的情况的一致的。
213 内存页与磁盘页
我们知道一般将内存看做磁盘的的缓存,有时MMU在工作时,会发现页表表明某个内存页不在物理内存中,此时会触发一个缺页异常(Page Fault),此时系统会到磁盘中相应的地方将磁盘页载入到内存中,然后重新执行由于缺页而失败的机器指令。关于这部分,因为可以看做对malloc实现是透明的,所以不再详细讲述,有兴趣的可以参考《深入理解计算机系统》相关章节。
最后附上一张在维基百科找到的更加符合真实地址翻译的流程供大家参考,这张图加入了TLB和缺页异常的流程(来源页)。
22 Linux进程级内存管理
221 内存排布
明白了虚拟内存和物理内存的关系及相关的映射机制,下面看一下具体在一个进程内是如何排布内存的。
以Linux 64位系统为例。理论上,64bit内存地址可用空间为0x0000000000000000 ~ 0xFFFFFFFFFFFFFFFF,这是个相当庞大的空间,Linux实际上只用了其中一小部分(256T)。
根据Linux内核相关文档描述,Linux64位操作系统仅使用低47位,高17位做扩展(只能是全0或全1)。所以,实际用到的地址为空间为0x0000000000000000 ~ 0x00007FFFFFFFFFFF和0xFFFF800000000000 ~ 0xFFFFFFFFFFFFFFFF,其中前面为用户空间(User Space),后者为内核空间(Kernel Space)。图示如下:
对用户来说,主要关注的空间是User Space。将User Space放大后,可以看到里面主要分为如下几段:
Code:这是整个用户空间的最低地址部分,存放的是指令(也就是程序所编译成的可执行机器码)
Data:这里存放的是初始化过的全局变量
BSS:这里存放的是未初始化的全局变量
Heap:堆,这是我们本文重点关注的地方,堆自低地址向高地址增长,后面要讲到的brk相关的系统调用就是从这里分配内存
Mapping Area:这里是与mmap系统调用相关的区域。大多数实际的malloc实现会考虑通过mmap分配较大块的内存区域,本文不讨论这种情况。这个区域自高地址向低地址增长
Stack:这是栈区域,自高地址向低地址增长
下面我们主要关注Heap区域的操作。对整个Linux内存排布有兴趣的同学可以参考其它资料。
222 Heap内存模型
一般来说,malloc所申请的内存主要从Heap区域分配(本文不考虑通过mmap申请大块内存的情况)。
由上文知道,进程所面对的虚拟内存地址空间,只有按页映射到物理内存地址,才能真正使用。受物理存储容量限制,整个堆虚拟内存空间不可能全部映射到实际的物理内存。Linux对堆的管理示意如下:
Linux维护一个break指针,这个指针指向堆空间的某个地址。从堆起始地址到break之间的地址空间为映射好的,可以供进程访问;而从break往上,是未映射的地址空间,如果访问这段空间则程序会报错。
223 brk与sbrk
由上文知道,要增加一个进程实际的可用堆大小,就需要将break指针向高地址移动。Linux通过brk和sbrk系统调用操作break指针。两个系统调用的原型如下:
int brk(voidaddr);
voidsbrk(intptr_t increment);
brk将break指针直接设置为某个地址,而sbrk将break从当前位置移动increment所指定的增量。brk在执行成功时返回0,否则返回-1并设置errno为ENOMEM;sbrk成功时返回break移动之前所指向的地址,否则返回(void )-1。
一个小技巧是,如果将increment设置为0,则可以获得当前break的地址。
另外需要注意的是,由于Linux是按页进行内存映射的,所以如果break被设置为没有按页大小对齐,则系统实际上会在最后映射一个完整的页,从而实际已映射的内存空间比break指向的地方要大一些。但是使用break之后的地址是很危险的(尽管也许break之后确实有一小块可用内存地址)。
224 资源限制与rlimit
系统对每一个进程所分配的资源不是无限的,包括可映射的内存空间,因此每个进程有一个rlimit表示当前进程可用的资源上限。这个限制可以通过getrlimit系统调用得到,下面代码获取当前进程虚拟内存空间的rlimit:
int main(){
struct rlimit limit =(struct rlimit )malloc(sizeof(struct rlimit));
getrlimit(RLIMIT_AS, limit);
printf("soft limit: %ld, hard limit: %ld\n", limit->rlim_cur, limit->rlim_max);
}
其中rlimit是一个结构体:
struct rlimit {
rlim_t rlim_cur;/ Soft limit /
rlim_t rlim_max;/ Hard limit (ceiling for rlim_cur) /
};
每种资源有软限制和硬限制,并且可以通过setrlimit对rlimit进行有条件设置。其中硬限制作为软限制的上限,非特权进程只能设置软限制,且不能超过硬限制。
3 实现malloc
31 玩具实现
在正式开始讨论malloc的实现前,我们可以利用上述知识实现一个简单但几乎没法用于真实的玩具malloc,权当对上面知识的复习:
/ 一个玩具malloc /
#include
#include
voidmalloc(size_t size)
{
voidp;
p = sbrk(0);
if(sbrk(size)==(void)-1)
return NULL;
return p;
}
这个malloc每次都在当前break的基础上增加size所指定的字节数,并将之前break的地址返回。这个malloc由于对所分配的内存缺乏记录,不便于内存释放,所以无法用于真实场景。
32 正式实现
下面严肃点讨论malloc的实现方案。
321 数据结构
首先我们要确定所采用的数据结构。一个简单可行方案是将堆内存空间以块(Block)的形式组织起来,每个块由meta区和数据区组成,meta区记录数据块的元信息(数据区大小、空闲标志位、指针等等),数据区是真实分配的内存区域,并且数据区的第一个字节地址即为malloc返回的地址。
可以用如下结构体定义一个block:
typedefstruct s_block t_block;
struct s_block {
size_t size;/ 数据区大小 /
t_block next;/ 指向下个块的指针 /
int free; / 是否是空闲块 /
int padding;/ 填充4字节,保证meta块长度为8的倍数 /
char data[1]/ 这是一个虚拟字段,表示数据块的第一个字节,长度不应计入meta /
};
由于我们只考虑64位机器,为了方便,我们在结构体最后填充一个int,使得结构体本身的长度为8的倍数,以便内存对齐。示意图如下:
322 寻找合适的block
现在考虑如何在block链中查找合适的block。一般来说有两种查找算法:
First fit:从头开始,使用第一个数据区大小大于要求size的块所谓此次分配的块
Best fit:从头开始,遍历所有块,使用数据区大小大于size且差值最小的块作为此次分配的块
两种方法各有千秋,best fit具有较高的内存使用率(payload较高),而first fit具有更好的运行效率。这里我们采用first fit算法。
/ First fit /
t_block find_block(t_block last,size_t size){
t_block b = first_block;
while(b &&!(b->free && b->size >= size)){
last = b;
b = b->next;
}
return b;
}
find_block从frist_block开始,查找第一个符合要求的block并返回block起始地址,如果找不到这返回NULL。这里在遍历时会更新一个叫last的指针,这个指针始终指向当前遍历的block。这是为了如果找不到合适的block而开辟新block使用的,具体会在接下来的一节用到。
323 开辟新的block
如果现有block都不能满足size的要求,则需要在链表最后开辟一个新的block。这里关键是如何只使用sbrk创建一个struct:
#define BLOCK_SIZE 24/ 由于存在虚拟的data字段,sizeof不能正确计算meta长度,这里手工设置 /
t_block extend_heap(t_block last,size_t s){
t_block b;
b = sbrk(0);
if(sbrk(BLOCK_SIZE + s)==(void)-1)
return NULL;
b->size = s;
b->next = NULL;
if(last)
last->next = b;
b->free =0;
return b;
}
324 分裂block
First fit有一个比较致命的缺点,就是可能会让很小的size占据很大的一块block,此时,为了提高payload,应该在剩余数据区足够大的情况下,将其分裂为一个新的block,示意如下:
实现代码:
void split_block(t_block b,size_t s){
t_block new;
new= b->data + s;
new->size = b->size - s - BLOCK_SIZE ;
new->next = b->next;
new->free =1;
b->size = s;
b->next =new;
}
325 malloc的实现
有了上面的代码,我们可以利用它们整合成一个简单但初步可用的malloc。注意首先我们要定义个block链表的头first_block,初始化为NULL;另外,我们需要剩余空间至少有BLOCK_SIZE + 8才执行分裂操作。
由于我们希望malloc分配的数据区是按8字节对齐,所以在size不为8的倍数时,我们需要将size调整为大于size的最小的8的倍数:
size_t align8(size_t s){
if(s &0x7==0)
return s;
return((s >>3)+1)<<3;
}
#define BLOCK_SIZE 24
voidfirst_block=NULL;
/ other functions /
voidmalloc(size_t size){
t_block b, last;
size_t s;
/ 对齐地址 /
s = align8(size);
if(first_block){
/ 查找合适的block /
last = first_block;
b = find_block(&last, s);
if(b){
/ 如果可以,则分裂 /
if((b->size - s)>=( BLOCK_SIZE +8))
split_block(b, s);
b->free =0;
}else{
/ 没有合适的block,开辟一个新的 /
b = extend_heap(last, s);
if(!b)
return NULL;
}
}else{
b = extend_heap(NULL, s);
if(!b)
return NULL;
first_block = b;
}
return b->data;
}
326 calloc的实现
有了malloc,实现calloc只要两步:
malloc一段内存
将数据区内容置为0
由于我们的数据区是按8字节对齐的,所以为了提高效率,我们可以每8字节一组置0,而不是一个一个字节设置。我们可以通过新建一个size_t指针,将内存区域强制看做size_t类型来实现。
voidcalloc(size_t number,size_t size){
size_tnew;
size_t s8, i;
new= malloc(number size);
if(new){
s8 = align8(number size)>>3;
for(i =0; i < s8; i++)
new[i]=0;
}
returnnew;
}
327 free的实现
free的实现并不像看上去那么简单,这里我们要解决两个关键问题:
如何验证所传入的地址是有效地址,即确实是通过malloc方式分配的数据区首地址
如何解决碎片问题
首先我们要保证传入free的地址是有效的,这个有效包括两方面:
地址应该在之前malloc所分配的区域内,即在first_block和当前break指针范围内
这个地址确实是之前通过我们自己的malloc分配的
第一个问题比较好解决,只要进行地址比较就可以了,关键是第二个问题。这里有两种解决方案:一是在结构体内埋一个magic number字段,free之前通过相对偏移检查特定位置的值是否为我们设置的magic number,另一种方法是在结构体内增加一个magic pointer,这个指针指向数据区的第一个字节(也就是在合法时free时传入的地址),我们在free前检查magic pointer是否指向参数所指地址。这里我们采用第二种方案:
首先我们在结构体中增加magic pointer(同时要修改BLOCK_SIZE):
typedefstruct s_block t_block;
struct s_block {
size_t size;/ 数据区大小 /
t_block next;/ 指向下个块的指针 /
int free; / 是否是空闲块 /
int padding;/ 填充4字节,保证meta块长度为8的倍数 /
voidptr; / Magic pointer,指向data /
char data[1]/ 这是一个虚拟字段,表示数据块的第一个字节,长度不应计入meta /
};
然后我们定义检查地址合法性的函数:
t_block get_block(voidp){
chartmp;
tmp = p;
return(p = tmp -= BLOCK_SIZE);
}
int valid_addr(voidp){
if(first_block){
if(p > first_block && p < sbrk(0)){
return p ==(get_block(p))->ptr;
}
}
return0;
}
当多次malloc和free后,整个内存池可能会产生很多碎片block,这些block很小,经常无法使用,甚至出现许多碎片连在一起,虽然总体能满足某此malloc要求,但是由于分割成了多个小block而无法fit,这就是碎片问题。
一个简单的解决方式时当free某个block时,如果发现它相邻的block也是free的,则将block和相邻block合并。为了满足这个实现,需要将s_block改为双向链表。修改后的block结构如下:
typedefstruct s_block t_block;
struct s_block {
size_t size;/ 数据区大小 /
t_block prev;/ 指向上个块的指针 /
t_block next;/ 指向下个块的指针 /
int free; / 是否是空闲块 /
int padding;/ 填充4字节,保证meta块长度为8的倍数 /
voidptr; / Magic pointer,指向data /
char data[1]/ 这是一个虚拟字段,表示数据块的第一个字节,长度不应计入meta /
};
合并方法如下:
t_block fusion(t_block b){
if(b->next && b->next->free){
b->size += BLOCK_SIZE + b->next->size;
b->next = b->next->next;
if(b->next)
b->next->prev = b;
}
return b;
}
有了上述方法,free的实现思路就比较清晰了:首先检查参数地址的合法性,如果不合法则不做任何事;否则,将此block的free标为1,并且在可以的情况下与后面的block进行合并。如果当前是最后一个block,则回退break指针释放进程内存,如果当前block是最后一个block,则回退break指针并设置first_block为NULL。实现如下:
void free(voidp){
t_block b;
if(valid_addr(p)){
b = get_block(p);
b->free =1;
if(b->prev && b->prev->free)
b = fusion(b->prev);
if(b->next)
fusion(b);
else{
if(b->prev)
b->prev->prev = NULL;
else
first_block = NULL;
brk(b);
}
}
}
328 realloc的实现
为了实现realloc,我们首先要实现一个内存复制方法。如同calloc一样,为了效率,我们以8字节为单位进行复制:
void copy_block(t_block src, t_block dst){
size_tsdata,ddata;
size_t i;
sdata = src->ptr;
ddata = dst->ptr;
for(i =0;(i 8)< src->size &&(i 8)< dst->size; i++)
ddata[i]= sdata[i];
}
然后我们开始实现realloc。一个简单(但是低效)的方法是malloc一段内存,然后将数据复制过去。但是我们可以做的更高效,具体可以考虑以下几个方面:
如果当前block的数据区大于等于realloc所要求的size,则不做任何操作
如果新的size变小了,考虑split
如果当前block的数据区不能满足size,但是其后继block是free的,并且合并后可以满足,则考虑做合并
下面是realloc的实现:
voidrealloc(voidp,size_t size){
size_t s;
t_block b,new;
voidnewp;
if(!p)
/ 根据标准库文档,当p传入NULL时,相当于调用malloc /
return malloc(size);
if(valid_addr(p)){
s = align8(size);
b = get_block(p);
if(b->size >= s){
if(b->size - s >=(BLOCK_SIZE +8))
split_block(b,s);
}else{
/ 看是否可进行合并 /
if(b->next && b->next->free
&&(b->size + BLOCK_SIZE + b->next->size)>= s){
fusion(b);
if(b->size - s >=(BLOCK_SIZE +8))
split_block(b, s);
}else{
/ 新malloc /
newp = malloc (s);
if(!newp)
return NULL;
new= get_block(newp);
copy_block(b,new);
free(p);
return(newp);
}
}
return(p);
}
return NULL;
}
33 遗留问题和优化
以上是一个较为简陋,但是初步可用的malloc实现。还有很多遗留的可能优化点,例如:
同时兼容32位和64位系统
在分配较大快内存时,考虑使用mmap而非sbrk,这通常更高效
可以考虑维护多个链表而非单个,每个链表中的block大小均为一个范围内,例如8字节链表、16字节链表、24-32字节链表等等。此时可以根据size到对应链表中做分配,可以有效减少碎片,并提高查询block的速度
可以考虑链表中只存放free的block,而不存放已分配的block,可以减少查找block的次数,提高效率
还有很多可能的优化,这里不一一赘述。下面附上一些参考文献,有兴趣的同学可以更深入研究。
用PS做金字的方法是:
1、新建白色背景文件,Ctrl+i反相;
2、打字,栅格化,ctrl+t调整大小;
3、双击图层调出“图层样式”,设置“斜面与浮雕”;
4、设置“投影”等,完成。
战国至西汉时期,国人偶用滑石制印,用于殉葬。元末,文人以花乳石制印,石材开始跻身艺术之林。中国印石的种类,细分起来约有数百种,其中以寿山石、青田石、昌化石和巴林石为佳,合称中国四大名石。至明代中叶时,印石的欣赏部位还仅侧重于印面,后推及至边款,然印石除石质外,纹理、色彩等仍未列入欣赏要素。随着青田、寿山、昌化等印石的大量开采,人们印石欣赏的视角渐渐扩大。
我们国家地大物博,但出产印石的地方却不是很多。有以地名而命石名的。也有以质地和色彩而命石名的,还有以开矿者或象形而命名的。在中国,印章石历史很是久远,从古至今,印章石一直为文人术心灵和思绪的寓体,陆游有诗云“花如解语嫌多事,石不能言最可有”,印石以其特有的色、纹、韵、刚、柔、形,无言地传文达意,以无声现有声。
注意看图中右下角印章上的字,这些印石的书籍资料均出自于此
150多册印石类的书籍资料目录:
《[古代玉器]昭明,利群》
《[珠宝玉石鉴定实训]张林扫描版》
《爱莲居士藏东汉画像石拓片》
《爱莲居士藏魏晋碑帖部分》
《爱莲居士收藏汉画像石小品拓片》
《安阳北齐陶瓦铭文》
《巴林彩石》
《巴林冻石》
《巴林福黄石》
《巴林鸡血石》
《巴林石水草系列》
《巴林石种典范》
《巴蜀地区佛教造像选粹》
《宝鸡地区出土西周青铜器珍拓》
《北京图书馆藏中国历代石刻拓本滙编选录》
《彩石凋刻工艺》
《彩石凋刻作品集》
《昌化石精品名品展网络展》
《大朴不凋—伊秉绶》
《当代印钮精品展示》
《东汉刑徒砖拓片》
《东周时期金属货币》
《豆庐赏石-五百年寿山芙蓉美石选集》
《端砚凋艺家罗卓成的作品欣赏》
《方宗珪论《寿山石》
《方宗珪《寿山石问答》
《福字大观》
《高式熊篆书[观月记]》
《古法印泥》
《关于印泥的使用》
《关中《秦汉陶录》
《虢季子白盘清末朱拓》
《韩天衡先生《豆庐刀式》》
《汉镜铭书法特展》
《汉司徒袁安碑》
《汉魏碑额题记》
《杭州文交所首场[溪泠印象]中国印石展精品欣赏》
《和斋 藏《秦汉陶佣铭文拓片》
《黄牧甫印谱(集墨拓、印蜕、印石相片、边款拓片为一身,绝对精美》
《几个珍藏的瓦当拓片》
《鉴识鸡血石》
《鉴识田黄》
《金乙堂晒篆刻刀》
《金乙堂造原色兰馨桂馥金丝楠木直方印床》
《金乙堂造篆刻刀》
《精磨八角纯钨钢刻刀》
《楷书边款技法jpg
《柯铭骥作品》
《来楚生篆书千字文册》
《览石斋精品素章大荟萃》
《李刚田篆书古诗百首》
《历代古钱图说》
《历代文物装饰文字图鉴》
《林飞作品选》
《林劭川的《寿山石作品-情系江南系列》
《林树岳作品选》
《林文举三色套章》
《洛阳所出汉晋刻划砖拓片15品》
《眉县《秦汉瓦当图录》
《美石系列第二集 印章》
《美石系列第一集 美石》
《美哉!青田素石》
《梦回《秦汉 瓦当实物之惊艳绝伦》
《明城墙砖拓片汇编》
《明清玉器识真·佩件》
《倪东方大师青田石凋精品欣赏》
《潘惊石作品选》
《奇异的巴林石》
《钱君陶篆书千字文册》
《秦汉瓦当拓片精品赏析》
《秦汉砖铭百种 汉砖部分》
《秦汉砖铭百种 秦砖部分》
《秦汉砖铭文》
《秦陶文新编 上编》
《秦陶文新编 下编》
《青田极品 蓝星》
《青田石图谱》
《清花瓷碗底花押欣赏》
《如何磨硬质合金篆刻刀》
《山西洪洞新出汉十六字吉语砖拓片集锦》
《陕西古代砖瓦图典》
《上海博物馆造像记原迹》
《十八罗汉贺新春》
《寿山石》
《寿山石宝典》
《寿山石的品种》
《寿山石凋名家作品欣赏》
《寿山石鉴藏指南》
《寿山石精美[国石魂]》
《寿山石精品》
《寿山石赏识 名贵石种 坑头石》
《寿山石赏识 名贵石种 田黄石(1)》
《寿山石赏识 名贵石种 田黄石》
《寿山石赏识-凋刻艺术-薄意》
《寿山石印章掠影》
《寿山石志》
《寿山石种表》
《寿山石种大全》
《寿山石种鉴真》
《寿字大观》
《水晶原石》
《四灵瓦当精品拓片》
《宋徽宗赵佶[神霄玉清万寿宫诏碑]》
《谈谈篆刻的临摹[陈茗屋]》
《谈篆刻刀之种种》
《田刚作品选》
《田老师作品欣赏》
《拓碑自己来》
《瓦当汇编之[战国画当]》
《吴昌硕篆书[小戎诗]》
《吴大澄临金文三种》
《吴让之临天发神谶碑册》
《西泠印社第三届印文化博览会名石》
《细说我知道的绿松石doc
《徐维着印石俏色巧凋作品选》
《徐维着作品选》
《玄密塔碑整拓》
《颜家庙碑》
《杨鲁安藏珍馆印章精选》
《一般材料硬度对照表》
《尹宙碑》
《印材收藏[袁慧敏]》
《印床的暗榫拼接法》
《印泥漫谈》
《印石鉴赏与收藏》
《印石抛光打磨上蜡流程》
《印石欣赏》
《硬质印材简论》
《玉凋精品欣赏》
《战国齐陶铭精拓》
《赵明边款的临习》
《治印三参》
《中国古代石刻纹样》
《中国古玉器图鉴 人物、动物和瓜果类》
《中国历代器物图册》
《中国历史博物馆藏陶文 磗文 瓦文》
《中国赏石大典rar
《中国《寿山石网-《寿山石种图谱》
《中国《寿山石印章艺术》
《中国印石》
《中国印四大名石 《巴林石》
《中国印四大名石 青田石》
《中国印四大名石 《寿山石》
《周《秦汉瓦当》
《朱拓瓦当》
《铸造铜印随想》
《砖拓20种》
《砖拓片》
《篆刻-美丽印石》
《篆刻边款技法与拓法介绍》
《祖庵所藏寿山石展》
欢迎分享,转载请注明来源:浪漫分享网
评论列表(0条)