版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
深入JavaJava内存分配原理精 2010-09-0910:09zl198751JavaEye博客字号:T|T 文将深入Java,详细讲解Java内存分配方面的知识。Java内存分配与管理是Java的技术之一,之前我们曾介绍过Java的内存管理与内存以及Java回收方面的知识,今天我们再次深入Java,详细介绍一下JavaJavanew◆非RAM:硬盘等永久空1、栈区(stack)—2、堆区(heap)—OS(static)—4—5—这是速度最快的地方数据位于和其他所有方式都不同的一个地方处理器的内部过器的数量十分有限以寄存器是根据需要由编译器分配我们对此没有直接的控制权也不可能在自己的程序里找到JVM寄存器用来存放当前系统状态。然而,基于移植性要求,JVM有的寄存器数目不能过多。否则,对于任何本身的寄存器个数小于JVM的移植目标机,要用常规来模拟高速寄存器,是比较的。同时JVM基于栈(Stack)的,这也使得它拥有的寄存器较少。JVM的寄存器包括下面四个PC程序计数寄optop操作数栈栈顶地址寄存器frame当前执行环境地址寄存器vars局部变量首地址寄存器这些寄存器长度均为32。PC记录程序执行步骤,其余optop,frame,varsJVM中对应地址,用来快速获取当前执行Java当在一段代码块定义一个变量时,Java量退出该作用域后,JavaJavanewJava动回收器来管理。在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的 变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的变量来堆中的数组或对象。变量就相当于是为数组或者对象起的一个名变量是普通的变量,定义时在栈中分配,变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用new产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有变量指向它的时候,才变为,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被回收器收走(释放掉)。这也是Java比较占内存的原因。静态static静态Static是指位于固定位置尽管仍在RAM里程序运行期间静态的数据将随时等候调用可用static关键字一个对象的特定元素是静态的但Java对象本身都不会不会置入静态空常数constant常数值通常直接置于程序代码内部这样做是安全的因为它们都不会改变的常数需要严格地可考虑将它们置入只读器ROM非RAM若数据完全独立于一个程序之外那么即使程序不运行了它们仍可存在并处在程序的控制范围之外其中两个最主要的例子便是流式对象和持久性对象对于流式对象对象会变成字节流通常会发给另一台机器而对于持久性对象我们可把它们保存在磁盘或磁带中即使程序中止运行它们仍可保持自己的状态不变之所以要设计这些类型的数据最主要的一个考虑便是把对象变成可在其他上存在的形式以后一旦需要还可重新变回一个普通的存在于RAM里的对象目前Java只提供了有限的持久性对象支持在未来的Java版本中有望提供对持久性更完善的支持。(constant常量池指的是在编译期被确定,并被保存在已编译的.class包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号,比如:虚拟机必须为每个被装载的类型一个常量池。常量池就是该类型所用到常量的一个有序集和,包括直接常量(string,integerfloatingpoint)和对其他类型,字段和方法的符号。对于String常量,它的值是在常量池中的。而JVM中的常量池在内存当中是以表的形式存在的,对于String类型,有一张固定长度的CONSTANT_String_info表用来文字字符串值,注意:该表只文字字符串值,不符号引用。说到这里,对常量池中的在程序执行的时候,常量池会在MethodArea,而不是堆中Javanew、newarray、anewarraymultianewarray放。堆是由回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。数据(int,short,long,byte,float,double,boolean,char)和对象句柄()。inta=intb=编译器先处理inta=3;首先它会在栈中创建一个变量为a的,然后查找栈中33a3intb3;在创建完b的变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出ab3这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会b要注意这种数据的共享与两个对象的同时指向一个对象的这种共享是不同的,因为这种情况ab,对象变量修改了这个对象的内部状态,会影响到另一个对象变量。Stringstr=newStringstr=new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。而第二种是先在栈中创建一个对String类的对象变量str,然后通过符号去字符串常量池里找有没有"abc",如果没有,则将"abc"存放进字strabc”,如果已经有”abc”str“abc”。比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的是否指向Stringstr1=Stringstr2=System.out.println(str1==str2);Stringstr1=newStringStringstr2=newStringSystem.out.println(str1==str2);//因此用第二种方式创建多个”abc”JVMStringstr=newStringstr="abc";的格式定义类时,总是Stringstr。担心陷阱!对象可能并没有被创建!而可能new()方法才能保证每次都创建一个新的对StringimmutableStringStringBuffernull,Stringnull;但它又是一种特殊的对象,有其它对象没有的一newString()newString(”")Stringstr=”kvill”;Stringstr=newString”kvill”)的区别StringStringStrings2="kv"+System.out.println(s0==s1System.out.println(s0==s2s0s1kvill”都是字符串常量,它们在编译期就被确定了,s2字符串常量,所以s2也是常量池中”kvill”的一个。所以我们得出s0==s1==s2;newString()newStringStringStrings1=newStrings2="kv"+newSystem.out.println(s0==s1System.out.println(s0==s2System.out.println(s1==s22s0"kvill”的应用,s1创建的新对象”kvill”的,s2因为有后半部分newString(”ill”)所以也无法在再补充介绍一点:存在于.classJVM充。Stringintern()Stringstrintern()方法时,JavaUnicode回其的,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引Strings0=Strings1=newStrings2=newSystem.out.println(s0==s1System.out.println("**********"s2=ern();//把常量池中"kvill"的赋给System.out.println(System.out.println(s0==ern()System.out.println(s0==ern(),s1ern()返回的是常量池中"kvill"的SernStringStringUnicode自己的地址到表中”如果我把他说的这个全局的String表理解为常量池的话,他的最后一句话,”如果在表中没有相同值的字符串,则将自己的地址到表中”是错的:Strings1=newStringSystem.out.println(s1==ern()System.out.println(s1+""+s2System.out.println(s2==ern()kvillkvillern()后就在常量池中新添加了一个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址到常量池中”了。true;而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的String说:Stringstr=”kv”+”ill”+”“+”ans4kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和””生成“kvill“存在内存中,最后又和生成了”kvillansstr,就是因为StringStringBufferStringBufferfinalStringBufferanewStringBuffer("111");finalStringBufferbnewStringBuffer("222");finalStringBufferanewStringBuffer("111");a.append("222");//编译通过可见,final只对的"值"(即内存地址)有效,它迫使只能指向初始指向的那finalStringa=Stringb="a"+System.out.println((a==b));//result=Stringa=Stringb="a"+System.out.println((a==b));//result=Stringa=Stringb="a"+System.out.println((a==b));//result=分析:JVM,JVM接优化为连接后的值,拿"a"+1classa1。在编译true。Stringa=Stringbb=Stringb="a"+System.out.println((a==b));//result=分析:JVM对于字符串,由于在字符串的"+"连接中,有字符串存在,而的值在程序编译期是无法确定的,即"a"bbbfalse。Stringa=finalStringbb=Stringb="a"+System.out.println((a==b));//result=分析:和[3bbfinalfinal在编译时被解析为常量值的一个本地拷贝到自己的常量池中或嵌入到它的字节码流中。所以此时的"a"+bba"+"btrue。Stringa=finalStringbb=Stringb="a"+System.out.println((a==b));//result=privatestaticStringgetBB()return}分析:JVM对于字符串bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"b,false。 "a"+"b"+Stringsa=b=c=s= StringBuffertemp=newStrings=String(+)效率低下原因分publicclassTestpublicstaticvoidmain(Stringargs[])Strings=for(inti=0;i<100;i++)s+=}}}StringBuilderappendStringBuilderappendStringBuilderappendN1StringBufferStringBuliderappendpublicclassTest4
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024综合居间代理采购合作合同版
- 2024石榴产业生态园投资合作协议书3篇
- 2025年度玻璃纤维增强复合材料销售合同3篇
- 2025年度旅游客车租赁与旅游交通配套服务合同3篇
- 2025年度购房赠送高端定制家具及装修一体化合同4篇
- 2025年碎石石粉行业人才培养与引进合同样本3篇
- 2025年度窗帘环保材料采购合同3篇
- 2025年度旅游项目投资合伙人合同范本3篇
- 2025年度铝灰处理废弃物处理项目环保验收合同4篇
- 2025年度旅游景区导游工作绩效评估合同4篇
- 高二物理竞赛霍尔效应 课件
- 金融数学-(南京大学)
- 基于核心素养下的英语写作能力的培养策略
- 现场安全文明施工考核评分表
- 亚什兰版胶衣操作指南
- 四年级上册数学教案 6.1口算除法 人教版
- DB32-T 3129-2016适合机械化作业的单体钢架塑料大棚 技术规范-(高清现行)
- 6.农业产值与增加值核算统计报表制度(2020年)
- 人工挖孔桩施工监测监控措施
- 供应商物料质量问题赔偿协议(终端)
- 物理人教版(2019)必修第二册5.2运动的合成与分解(共19张ppt)
评论
0/150
提交评论