之前在公司听了一门关于java
内存占用方面的讲座,收获颇丰,回来后在eclipse
下进行了一些简单的尝试,但是实验遇到了一些小小的问题,通过向大牛咨询和查资料的方式逐渐将这些问题解决了,现在将我在这些实验中遇到的问题,已经解决的方法和大家分享下,希望各位指点其中的错误,谢谢!
Java
环境:
Java
version "1.6.0_24"
Java(TM)
SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Client VM (build
19.1-b02,mixed mode, sharing)
设置JVM
启动参数为 -Xms12m -Xmx12m
,然后运行如下程序:
public class MemTest {
public static void main(String[] args) {
int[] intArray = new int[2*1024*1024];
}
}
程序运行后出现:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at thread.ThreadCount.main(ThreadCount.java:6)
说明程序运行时堆内存溢出。
存在疑问:
在java
中,每个int
占4
字节,这个int
数组共有2*1024*1024
个int
类型,那我们可以推断出这个int
数据占据了大约8M
,而且这些空间是在内存堆中开辟的。现在我们已设置好内存堆有12M
的空间,也就是说除去程序其他内存堆开销整个堆内存应该剩下将近4m
,但是此处运行后,程序发生内存堆不够的内存溢出。
疑问解答:
之所以遇到上面的问题是因为我们所使用的Java
HotSpot(TM)
虚拟机是一种分代式的结构,其主要结构如下所示:
此种类型的GC
堆分成了三代,分别是Young Generation
、Old Generation
(Tenured
)、Permanent Generation
。
其中Young Generation
由Eden
、S0
、S1
(就是图上说的survivor
和spaces
区)组成,它主要负责存放新生成的对象,当Eden
区满时,还存活的对象被复制到S0
,当S0
满时,复制到S1
,当S1
满时将从S0
复制过来的且存活的对象复制到Old Generation
。其中S0
和S1
两个区是对称的,没有先后关系,一个S
区中可能存在着从Eden
或是另一个S
区复制过来的对象,而只有从另一个S
区复制过来的数据才能继续复制到老年区。而
而Old Generation
区中存放的从Young
区复制来的存活对象,都是生命周期较长的对象。
另外,Permanent Generation
对应着JVM
规范中的方法区,主要存放一些静态成员、常量,在HotPot VM
中可使用-XX:PermSize
–XX:MaxPermSize
对此区域进行调节。
在试验中新建的intArray
数组,需要连续的内存空间存储且一个对象不能跨代存储,也就是说,我们新建的对象大小不能超过了GC
堆中空间最大的一代,一般情况下,最大的代是Old Generation
,因此当intArray
数组对象为8M
时,可能已经超过了Old Generation
的大小,所以发生内存溢出异常。
了解完HotSpot
的构造后,我们来看看为什么之前的代码会发生内存溢出。这个因为在试验中新建的intArray
数组,需要连续的内存空间存储且一个对象不能跨代存储,也就是说,我们新建的对象大小不能超过了GC
堆中空间最大的一代,一般情况下,最大的代是Old Generation
,因此当intArray
数组对象为8M
时,已经超过了Old Generation
的大小,所以发生内存溢出异常。
- 大小: 23.6 KB
分享到:
相关推荐
- **实验截图**:通过实验过程中的输出,观察系统内存使用情况的变化。 - **数据处理**:根据实验前后的内存状态数据,分析内存分配与释放对系统性能的影响。 #### 分析与讨论 - 通过本次实验,深入了解了Windows...
Java 实现内存动态分配主要涉及Java内存模型以及内存管理机制,包括堆内存和栈内存的分配,以及垃圾回收等概念。下面将详细解释这些知识点。 1. **Java内存模型** Java程序运行时,内存分为堆内存(Heap)和栈内存...
5. **JAVA 16特性**:虽然实验主要关注内存管理概念,但使用JAVA 16也可能引入一些新的语言特性和工具,如Records、Pattern Matching for instanceof、开关表达式等,这为程序的开发提供了便利。 6. **实验价值**:...
这部分实验使用**位示图**作为数据结构来跟踪哪些页面是空闲的,哪些是被占用的,从而实现高效的空间分配与回收。 #### 实验环境 - **操作系统**:Windows 7 - **开发工具**:Visual Studio 2010 - **编程语言**:...
在这个实验中,我们将使用Java编程语言来实现内存管理的模拟,这为学习者提供了一个直观的实践平台,以便更好地理解抽象的内存分配和回收机制。 内存管理是操作系统的关键任务之一,它涉及如何有效地分配、使用和...
为了监控和分析Java内存管理,我们可以使用各种工具,如VisualVM、JConsole、JProfiler等,它们可以帮助我们查看内存使用情况、垃圾收集日志,甚至进行实时调优。 8. **源码分析** 对于深入理解Java内存管理,...
在本实验报告中,我们将重点讨论Linux操作系统中的请求分页内存管理,这是一个模拟实验,旨在帮助理解内存管理的基本概念和技术。 请求分页是现代操作系统中广泛采用的一种内存管理策略,它允许进程在需要时请求页...
此外,内存回收(例如,垃圾收集)也是操作系统中的关键任务,需要确保没有未使用的内存块被永久占用。 总之,这个实验提供了一个实践平台,让学生能够探索和比较不同的内存分配策略,理解它们的优缺点,为未来在...
【实验五】关注访问控制(public, private, protected, default)和封装类的设计,同时讲解了内部类的概念,以及Java内存管理与垃圾收集机制,帮助理解Java对象生命周期和内存管理策略。 【实验六】重点在于异常...
使用java来实现模拟的内存管理 有分配内存 回收内存等功能 有可视化效果 可以很清楚的看到内存的分配情况
实验标题"JAVA实验报告 处理大整数"涉及的核心知识点是使用`java.math.BigInteger`类来处理任意精度的整数运算。这个实验在Eclipse开发环境中进行,旨在帮助学生熟悉并掌握`BigInteger`类的常用方法。 `BigInteger`...
这个实验是用Java语言编写的,这使得我们可以利用Java的强大特性和跨平台性来模拟内存的复杂行为。 动态内存管理是编程中的一个重要部分,特别是在操作系统中。它是指在程序运行时根据需要动态地分配和释放内存。这...
实验5的Java常用类主要涵盖了Java编程中的一些核心概念和常用工具类的使用。以下是这些知识点的详细说明: 1. **String、StringBuffer(StringBuilder)**: - **String** 类在Java中是不可变的,这意味着一旦创建了...
2. **数据结构**:为了跟踪内存使用情况,我们需要维护两个数据结构:已分区表和空闲分区表(或链表)。已分区表记录了被占用的内存分区,包括分区ID、起始地址、长度和占用状态。空闲分区表则记录所有未被分配的...
【Java小动画设计实验报告】 本实验报告主要探讨如何利用Java编程语言设计一款趣味小动画,结合了双缓冲技术以及音频处理,旨在提高程序的执行效率和用户体验。实验旨在通过实际操作,深化对Java语言的理解,尤其是...
Java的特点包括自动内存管理(垃圾回收机制)、严格的类型检查以及跨平台的Java虚拟机(JVM),这使得Java在企业级应用、网络服务、移动开发等领域都有着广泛的应用。 本书的重点在于实验指导,这意味着它将理论...
在本实验报告中,我们将深入探讨Java编程语言中的核心数据结构。数据结构是计算机科学的基础,它涉及到如何高效地组织和存储数据,以便于访问和处理。Java版本的数据结构实验旨在帮助学生理解并掌握这些概念,并能...
7. **复制文件**:在实验中可能用到了FileUtils.copyFile()方法(来自Apache Commons IO库)或使用Java 7引入的Files.copy()方法来实现文件的复制。 8. **读写文件内容**:使用FileWriter的write()方法写入文本,...
基于Java的操作系统进程调度器与内存管理源码+实验论文(操作系统课程实验).zip基于Java的操作系统进程调度器与内存管理源码+实验论文(操作系统课程实验).zip基于Java的操作系统进程调度器与内存管理源码+实验论文...
JAVA简单记事本程序设计实验报告是一份详细记录了如何使用Java编程语言开发一个简易记事本应用程序的文档。这个程序旨在实现基本的文本编辑功能,包括文件操作(新建、打开、保存、退出)和编辑操作(剪切、拷贝、...