
唯一的目的是存储对象实例。几乎所有对象实例都在此处分配内存。这一点在Java中是虚拟的
伪机规范中的描述是:必须在堆①上分配所有对象实例和数组,但必须使用JIT编译器
逃生分析技术,堆栈分配,标量替换的发展和逐步成熟②优化技术会带来一些微妙之处
发生了更改,所有对象都分配到了堆上,并逐渐变得“绝对”。
Java堆是垃圾收集器管理的主要区域,因此通常称为“ GC堆”(Garbage
所收集的堆很幸运,在中国没有被翻译成“垃圾堆”。从内存恢复的角度来看,因为现在
收集器基本上采用世代收集算法,因此Java堆也可以细分为:新一代和旧一代;
更详细的是Eden空间,From Survivor空间,To Survivor空间等。如果从内存中分配
从角度来看,线程共享的Java堆可以分为多个线程专用分配缓冲区(线程本地
分配缓冲区,TLAB)。但是,无论划分如何,都与存储内容无关,无论在哪个区域,
存储仍然是对象实例,进一步划分的目的是更好地回收内存或更快地分配
内存。在本章中,我们仅讨论内存区域(上述区域在Java堆中)的作用
诸如分配和回收之类的细节将是下一章的主题。
根据Java虚拟机规范,Java堆可以位于物理上不连续的内存空间中,只要
它在逻辑上是连续的,就像我们的磁盘空间一样。在实现中,可以将其实现为固定大小
它也可以是可扩展的,但是当前的主流虚拟机是根据可扩展性实现的(通过-Xmx
和-Xms控件)。如果堆中没有内存来完成实例分配,并且无法再扩展堆,它将抛出
OutOfMemoryError异常。
4、方法区域
方法区,就像Java堆一样,是每个线程共享的内存区,用于存储
存储由虚拟机加载的数据,例如类信息,常量,静态变量和由即时编译器编译的代码。虽然
尽管Java虚拟机规范将方法区域描述为堆的逻辑部分,但它具有一个名为Non-
的别名。
堆(非堆),目的是将其与Java堆区分开。
对于习惯于在HotSpot虚拟机上开发和部署程序的开发人员,很都愿意使用方法区域
它称为“永久一代”。从本质上讲,两者不是等效的,只是因为HotSpot是虚拟的
模拟机的设计团队选择将GC世代集合扩展到方法区域,或使用永久生成来实现方法区域。
已经。对于其他虚拟机(例如BEA JRockit,IBM J9等),没有永久生成的概念。即
它是HotSpot虚拟机本身。根据官方路线图信息,它现在也放弃了永久的一代,并“在移动”
转到“本机内存”以实现方法区域的计划。
Java虚拟机规范对此区域有非常宽松的限制,只是它不需要像Java堆这样的连续内存
除了选择固定大小或可扩展的存储之外,还可以选择不实施垃圾收集。相对来说,垃圾

在该区域中收集行为相对较少,但是数据进入方法区域并不是永久代的名称。
这种“永久”存在。该区域的内存恢复目标主要是恢复常量池和卸载类型
负载,一般来讲,这方面的恢复“得分”更难以满足,尤其是卸载类型,条件
非常严酷,但是在这一领域的回收确实是必要的。在Sun公司的BUG列表中,曾经出现过
过去的一些严重错误是由于HotSpot虚拟机的低版本无法完全收回该区域造成的。
导致内存泄漏。
根据Java虚拟机规范,当方法区域不能满足内存分配要求时,它将抛出
OutOfMemoryError异常。
5、运行时常量池
运行时常量池是方法区域的一部分。除了课程文件
除了描述版本,字段,方法,接口和该类的其他信息外,还提供有关常量池(Constant Pool)的信息
表),用于存储在编译期间生成的各种文字和符号引用。内容的这一部分将在加载类后存储
转到方法区域中的运行时常量池。
Java虚拟机对Class文件各部分的格式(自然包括常量池)有严格的规定
确定每个字节用于存储哪种数据必须符合规范的要求,以便虚拟机可以识别。
加载并执行。但是对于运行时常量池,Java虚拟机规范没有提出任何详细的要求,
提供者实现的虚拟机可以根据自己的需求实现此内存区域。但是,除了
除了保存Class文件中描述的符号引用外,转换后的直接引用也存储在运行时中
在测量池①。
与类文件常量池相比,运行时常量池的另一个重要功能是其动态性质。 Java语言
不需要常量必须仅在编译时生成,也就是说,它们不必预先构建在Class文件中常量池的内容中
您可以在方法区域中输入运行时常量池,也可以在运行时将新的常量放入池中。此功能已开发
人们更频繁地使用String类的intern()方法。
由于运行时常量池是方法区域的一部分,因此它自然会受到方法区域内存的限制。当常量池不可用时
该方法将在再次申请内存时抛出OutOfMemoryError
6、直接存储
在运行虚拟机时,直接内存(Direct Memory)不属于数据区域,也不是Java
虚拟机规范中定义的内存区域,但是这部分内存也经常使用,也可能导致
发生OutOfMemoryError,所以让我们在这里一起解释。
在JDK1.4中,新添加了NIO(新输入/输出)类,并引入了基于通道的(Channel)。
缓冲区的I / O方法(Buffer),它可以使用Native函数库直接分配堆外内存,但是
然后使用存储在Java堆中的DirectByteBuffer对象对此内存进行引用
操作。在某些情况下,这可以显着提高性能,因为它避免了使用Java堆和本机堆
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-354051-1.html
千玺
我昨天才在超市挑选黑芝麻
但慢慢的就有人开始说道了