`
燈小嗨
  • 浏览: 14517 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
社区版块
存档分类
最新评论

JAVA内存占用情况实验

阅读更多

之前在公司听了一门关于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*1024int 类型,那我们可以推断出这个int 数据占据了大约8M ,而且这些空间是在内存堆中开辟的。现在我们已设置好内存堆有12M 的空间,也就是说除去程序其他内存堆开销整个堆内存应该剩下将近4m ,但是此处运行后,程序发生内存堆不够的内存溢出。

疑问解答:

之所以遇到上面的问题是因为我们所使用的Java HotSpot(TM) 虚拟机是一种分代式的结构,其主要结构如下所示:

HotSpot Jvm内存堆结构

此种类型的GC 堆分成了三代,分别是Young GenerationOld GenerationTenured )、Permanent Generation

其中Young GenerationEdenS0S1 (就是图上说的survivorspaces 区)组成,它主要负责存放新生成的对象,当Eden 区满时,还存活的对象被复制到S0 ,当S0 满时,复制到S1 ,当S1 满时将从S0 复制过来的且存活的对象复制到Old Generation 。其中S0S1 两个区是对称的,没有先后关系,一个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
2
12
分享到:
评论
10 楼 燈小嗨 2011-10-10  
newjavaconte12 写道
到底谁是对的啊


对象只能存放于young或old两代中,是不能跨代存储的,perm是存放类的静态变量等东西,就是jvm规范中提到的方法区,不存放对象。
9 楼 newjavaconte12 2011-10-09  
到底谁是对的啊
8 楼 langyu 2011-10-03  
燈小嗨 写道
那你的意思是,对象可以跨代存储了?

堆内容有三个代,我们创建的对象只能存放于young或old,而不能跑到perm区。
7 楼 燈小嗨 2011-10-03  
langyu 写道
引用
也就是说,我们新建的对象大小不能超过了GC 堆中空间最大的一代

你听谁这样说的?



那你的意思是,对象可以跨代存储了?
6 楼 燈小嗨 2011-10-03  
1927105 写道
推荐lz看一本分布式应用一书,里面挺有用的。


能推荐一本不?
5 楼 燈小嗨 2011-10-03  
zhouguiping2008 写道


当这个tenured代超过70%就会执行又一次全垃圾收集,回收之后还在70%以上也可能抛出内存溢出



恩,加上参数XX:NewRatio=4,同时查看heap内存变化验证了你的说法。

但我有疑问的是,这个触发FGC的阈值是根据不同垃圾收集器来定的吧?70%应该不一定吧?
4 楼 zhouguiping2008 2011-10-03  
分析的有点强求,

其实溢出的原理是这样的,你分配了12M的堆内存,但是没有指定各个代的分配策略,也就是采用jvm的默认分配策略,-XX:SurvivorRatio=8,-XX:NewRatio=2,老年代和年轻代的比例是2,这个时候young分配的空间是4M空间,tenured分了8M,每个survivor代分了0.4M,eden分了3.2M,你实例化了一个8M大小的对象,由于eden代没有这么大的空间来存放这个对象,所以直接把这个对象分配到tenured代中,而这个代中总共也只有8M,当然会抛出内存溢出啊,而且当这个tenured代超过70%就会执行又一次全垃圾收集,回收之后还在70%以上也可能抛出内存溢出。如果你手动设置参数-XX:NewRatio=4就不会内存溢出了,现在知道了原因了吧。
3 楼 1927105 2011-10-03  
推荐lz看一本分布式应用一书,里面挺有用的。
2 楼 1927105 2011-10-03  
langyu 写道
引用
也就是说,我们新建的对象大小不能超过了GC 堆中空间最大的一代

你听谁这样说的?


难道是剩余的堆栈空间?
1 楼 langyu 2011-10-03  
引用
也就是说,我们新建的对象大小不能超过了GC 堆中空间最大的一代

你听谁这样说的?

相关推荐

    《系统内存统计使用》实验报告

    - **实验截图**:通过实验过程中的输出,观察系统内存使用情况的变化。 - **数据处理**:根据实验前后的内存状态数据,分析内存分配与释放对系统性能的影响。 #### 分析与讨论 - 通过本次实验,深入了解了Windows...

    java实现内存动态分配

    Java 实现内存动态分配主要涉及Java内存模型以及内存管理机制,包括堆内存和栈内存的分配,以及垃圾回收等概念。下面将详细解释这些知识点。 1. **Java内存模型** Java程序运行时,内存分为堆内存(Heap)和栈内存...

    JAVA操作系统实验存储管理图形化模拟程序

    5. **JAVA 16特性**:虽然实验主要关注内存管理概念,但使用JAVA 16也可能引入一些新的语言特性和工具,如Records、Pattern Matching for instanceof、开关表达式等,这为程序的开发提供了便利。 6. **实验价值**:...

    模拟内存分配实验报告

    这部分实验使用**位示图**作为数据结构来跟踪哪些页面是空闲的,哪些是被占用的,从而实现高效的空间分配与回收。 #### 实验环境 - **操作系统**:Windows 7 - **开发工具**:Visual Studio 2010 - **编程语言**:...

    操作系统实验 内存管理 java编写 有界面

    在这个实验中,我们将使用Java编程语言来实现内存管理的模拟,这为学习者提供了一个直观的实践平台,以便更好地理解抽象的内存分配和回收机制。 内存管理是操作系统的关键任务之一,它涉及如何有效地分配、使用和...

    操作系统实验和课设,java实现动态内存分配和回收,FF,NF,WF,BF

    此外,内存回收(例如,垃圾收集)也是操作系统中的关键任务,需要确保没有未使用的内存块被永久占用。 总之,这个实验提供了一个实践平台,让学生能够探索和比较不同的内存分配策略,理解它们的优缺点,为未来在...

    java内存管理

    为了监控和分析Java内存管理,我们可以使用各种工具,如VisualVM、JConsole、JProfiler等,它们可以帮助我们查看内存使用情况、垃圾收集日志,甚至进行实时调优。 8. **源码分析** 对于深入理解Java内存管理,...

    java实验报告.docx

    【实验五】关注访问控制(public, private, protected, default)和封装类的设计,同时讲解了内部类的概念,以及Java内存管理与垃圾收集机制,帮助理解Java对象生命周期和内存管理策略。 【实验六】重点在于异常...

    操作系统 linux 请求分页 模拟内存管理实验报告java(内含源码)

    在本实验报告中,我们将重点讨论Linux操作系统中的请求分页内存管理,这是一个模拟实验,旨在帮助理解内存管理的基本概念和技术。 请求分页是现代操作系统中广泛采用的一种内存管理策略,它允许进程在需要时请求页...

    java可视化 内存管理实验

    使用java来实现模拟的内存管理 有分配内存 回收内存等功能 有可视化效果 可以很清楚的看到内存的分配情况

    JAVA实验报告 处理大整数

    实验标题"JAVA实验报告 处理大整数"涉及的核心知识点是使用`java.math.BigInteger`类来处理任意精度的整数运算。这个实验在Eclipse开发环境中进行,旨在帮助学生熟悉并掌握`BigInteger`类的常用方法。 `BigInteger`...

    操作系统模拟内存管理实验

    这个实验是用Java语言编写的,这使得我们可以利用Java的强大特性和跨平台性来模拟内存的复杂行为。 动态内存管理是编程中的一个重要部分,特别是在操作系统中。它是指在程序运行时根据需要动态地分配和释放内存。这...

    实验5 JAVA常用类.doc

    实验5的Java常用类主要涵盖了Java编程中的一些核心概念和常用工具类的使用。以下是这些知识点的详细说明: 1. **String、StringBuffer(StringBuilder)**: - **String** 类在Java中是不可变的,这意味着一旦创建了...

    java小动画设计实验报告

    【Java小动画设计实验报告】 本实验报告主要探讨如何利用Java编程语言设计一款趣味小动画,结合了双缓冲技术以及音频处理,旨在提高程序的执行效率和用户体验。实验旨在通过实际操作,深化对Java语言的理解,尤其是...

    Java大学实用教程实验指导[耿祥义编著][习题解答]

    Java的特点包括自动内存管理(垃圾回收机制)、严格的类型检查以及跨平台的Java虚拟机(JVM),这使得Java在企业级应用、网络服务、移动开发等领域都有着广泛的应用。 本书的重点在于实验指导,这意味着它将理论...

    Java版本数据结构实验报告

    在本实验报告中,我们将深入探讨Java编程语言中的核心数据结构。数据结构是计算机科学的基础,它涉及到如何高效地组织和存储数据,以便于访问和处理。Java版本的数据结构实验旨在帮助学生理解并掌握这些概念,并能...

    java文件流学习实验

    7. **复制文件**:在实验中可能用到了FileUtils.copyFile()方法(来自Apache Commons IO库)或使用Java 7引入的Files.copy()方法来实现文件的复制。 8. **读写文件内容**:使用FileWriter的write()方法写入文本,...

    基于Java的操作系统进程调度器与内存管理源码+实验论文(操作系统课程实验).zip

    基于Java的操作系统进程调度器与内存管理源码+实验论文(操作系统课程实验).zip基于Java的操作系统进程调度器与内存管理源码+实验论文(操作系统课程实验).zip基于Java的操作系统进程调度器与内存管理源码+实验论文...

    JAVA简单记事本程序设计实验报告(带源码)

    JAVA简单记事本程序设计实验报告是一份详细记录了如何使用Java编程语言开发一个简易记事本应用程序的文档。这个程序旨在实现基本的文本编辑功能,包括文件操作(新建、打开、保存、退出)和编辑操作(剪切、拷贝、...

    华农Java综合性实验手写界面代码

    实验目的:综合运用Java语言和面向对象技术开发一个小型软件系统 实验内容: 1. 已经提供的原始数据:班级成绩单文件 该文件为文本文件,存储某个班的所有学生某门课程的成绩。 例如:2012级计算机科学与技术8班-...

Global site tag (gtag.js) - Google Analytics