- 1、本文档共17页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
深入Java 核心 Java 内存分配原理精讲
引言:栈、堆、常量池虽同属Java 内存分配时操作的区域,但其适用范围和功用却大不相同。本文将深入
Java 核心,详细讲解Java 内存分配方面的知识。
Java 内存分配与管理是Java 的核心技术之一,之前我们曾介绍过Java 的内存管理与
内存泄露以及Java 垃圾回收方面的知识,今天我们再次深入Java 核心,详细介绍一下Java
在内存分配方面的知识。一般Java 在内存分配时会涉及到以下区域:
◆寄存器:我们在程序中无法控制
◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中
◆堆:存放用new 产生的数据
◆静态域:存放在对象中用static 定义的静态成员
◆常量池:存放常量
◆非RAM 存储:硬盘等永久存储空间
Java 内存分配中的栈
在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配。
当在一段代码块定义一个变量时,Java 就在栈中 为这个变量分配内存空间,当该变量退出
该作用域后,Java 会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作
他用。
Java 内存分配中的堆
堆内存用来存放由new 创建的对象和数组。在堆中分配的内存,由Java 虚拟机的自动垃圾
回收器来管理。
在堆中产生了一个数组或对象后,还可以 在栈中定义一个特殊的变量,让栈中这个变量的
取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。
引用变量就相当于是 为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变
量来访问堆中的数组或对象。引用变量就相当于是为数组或者对象起的一个名称。
引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。
而数组和对象本身在堆中分配,即使程序 运行到使用 new 产生数组或者对象的语句所在的
代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的
时候,才变为垃圾,不能在被使用,但仍 然占据内存空间不放,在随后的一个不确定的时
间被垃圾回收器收走(释放掉)。这也是 Java 比较占内存的原因。
实际上,栈中的变量指向堆内存中的变量,这就是Java 中的指针!
常量池 (constant pool)
常量池指的是在编译期被确定,并被保存在已编译的.class 文件中的一些数据。除了包含
代码中所定义的各种基本类型(如int、long 等等)和对象型(如String 及数组)的常量
值(final)还包含一些以文本形式出现的符号引用,比如:
◆类和接口的全限定名;
◆字段的名称和描述符;
◆方法和名称和描述符。
虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序
集和,包括直接常量(string,integer 和 floating point 常量)和对其他类型,字段和方
法的符号引用。
对于String 常量,它的值是在常量池中的。而JVM 中的常量池在内存当中是以表的形式存
在的, 对于String 类型,有一张固定长度的CONSTANT_String_info 表用来存储文字字符
串值,注意:该表只存储文字字符串值,不存储符号引 用。说到这里,对常量池中的字符
串值的存储位置应该有一个比较明了的理解了。
在程序执行的时候,常量池 会储存在Method Area,而不是堆中。
堆与栈
Java 的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、
anewarray 和multianewarray 等指令建立,它们不需要程序代码来显式的释放。堆是由垃
圾回收来负责的,堆的优势是可以动态地分配内存 大小,生存期也不必事先告诉编译器,
因为它是在运行时动态分配内存的,Java 的垃圾收集器会自动收走这些不再使用的数据。
但缺点是,由于要在运行时动态 分配内存,存取速度较慢。
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的
数据大小与生存期必须是 确定的,缺乏灵活性。栈中主要存放一些基本类型的变量数据(int,
short, long, byte, float, double, boolean, char)和对象句柄(引用)。
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
1. Int a = 3;
2. Int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a 的引用,然后查找栈中是否有
3 这个
文档评论(0)