标签:实例 线程 方便 back 加载 output 代码 overflow 独立
JVM 运行时数据区 (JVM Runtime Area) 其实就是指 JVM 在运行期间,其对JVM内存空间的划分和分配。网上找到两幅图如下所示(个人认为第二个图Native Method Stack应该画在Java Thead模块中):
栈分为java虚拟机栈和本地方法栈
名称
特征
作用
配置参数
异常
程序计数器
占用内存小,线程私有,生命周期与线程相同
大致为字节码行号指示器
无
虚拟机栈
线程私有,生命周期与线程相同,使用连续的内存空间
Java 方法执行的内存模型,存储局部变量表、操作栈、动态链接、方法出口等信息
-Xss
StackOverflowError
OutOfMemoryError
java堆
线程共享,生命周期与虚拟机相同,可以不使用连续的内存地址
保存对象实例,所有对象实例(包括数组)都要在堆上分配
-Xms
-Xsx
-Xmn
方法区
存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
-XX:PermSize:16M
-XX:MaxPermSize:64M
运行时常量池
方法区的一部分,具有动态性
存放字面量及符号引用
直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError 异常出现,所以我们放到这里一起讲解。
在JDK 1.4 中新加入了NIO(NewInput/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用Native 函数库直接分配堆外内存,然后通过一个存储在Java 堆里面的DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java 堆和Native 堆中来回复制数据。
经常有人把Java 内存区分为堆内存(Heap)和栈内存(Stack),这种分法比较粗糙,Java内存区域的划分实际上远比这复杂。这种划分方式的流行只能说明大多数程序员最关注的、与对象内存分配关系最密切的内存区域是这两块。
堆很灵活,但是不安全。对于对象,我们要动态地创建、销毁,不能说后创建的对象没有销毁,先前创建的对象就不能销毁,那样的话我们的程序就寸步难行,所以Java中用堆来存储对象。而一旦堆中的对象被销毁,我们继续引用这个对象的话,就会出现著名的 NullPointerException,这就是堆的缺点——错误的引用逻辑只有在运行时才会被发现。
栈不灵活,但是很严格,是安全的,易于管理。因为只要上面的引用没有销毁,下面引用就一定还在,在大部分程序中,都是先定义的变量、引用先进栈,后定义的后进栈,同时,区块内部的变量、引用在进入区块时压栈,区块结束时出栈,理解了这种机制,我们就可以很方便地理解各种编程语言的作用域的概念了,同时这也是栈的优点——错误的引用逻辑在编译时就可以被发现。
栈--主要存放引用和基本数据类型。
堆--用来存放 new 出来的对象实例。
参考:http://blog.csdn.net/u012152619/article/details/46968883
java虚拟机:JVM内存模型
原文地址:http://www.cnblogs.com/xiaotian15/p/6912615.html