`
hejiajunsh
  • 浏览: 410038 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

JAVA的内存模型及结构

阅读更多

原文链接   译文链接  作者:Tai Truong    译者:Jaxon

所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?

Java内存模型

Java内存模型在JVM specification, Java SE 7 Edition, and mainly in the chapters “2.5 Runtime Data Areas” and “2.6 Frames”中有详细的说明。对象和类的数据存储在3个不同的内存区域:堆(heap space)、方法区(method area)、本地区(native area)。

堆内存存放对象以及数组的数据,方法区存放类的信息(包括类名、方法、字段)、静态变量、编译器编译后的代码,本地区包含线程栈、本地方法栈等存放线程

JUtH_20121024_RuntimeDataAreas_1_MemoryModel (1)
 

方法区有时被称为持久代(PermGen)。

JUtH_20121024_RuntimeDataAreas_2_MemoryModel (1)

所有的对象在实例化后的整个运行周期内,都被存放在堆内存中。堆内存又被划分成不同的部分:伊甸区(Eden),幸存者区域(Survivor Sapce),老年代(Old Generation Space)。

方法的执行都是伴随着线程的。原始类型的本地变量以及引用都存放在线程栈中。而引用关联的对象比如String,都存在在堆中。为了更好的理解上面这段话,我们可以看一个例子:

01 import java.text.SimpleDateFormat;
02 import java.util.Date;
03  
04 import org.apache.log4j.Logger;
05  
06 public class HelloWorld {
07     private static Logger LOGGER = Logger.getLogger(HelloWorld.class.getName());
08  
09     public void sayHello(String message) {
10         SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.YYYY");
11         String today = formatter.format(new Date());
12         LOGGER.info(today + ": " + message);
13     }
14 }

这段程序的数据在内存中的存放如下:

JUtH_20121024_RuntimeDataAreas_4_MemoryModel

通过JConsole工具可以查看运行中的Java程序(比如Eclipse)的一些信息:堆内存的分配,线程的数量以及加载的类的个数;

JUtH_20121024_RuntimeDataAreas_5_JConsole

 Java内存结构

这里有一份极好的白皮书:Memory Management in the Java HotSpot Virtual Machine。它描述了垃圾回收(GC)触发的内存自动管理。Java的内存结构包含如下部分:

JUtH_20121024_RuntimeDataAreas_6_MemoryModel

堆内存

堆内存同样被划分成了多个区域:

  • 包含伊甸(Eden)和幸存者区域(Survivor Sapce)的新生代(Young generation)
  • 老年代(Old Generation)

不同区域的存放的对象拥有不同的生命周期:

  • 新建(New)或者短期的对象存放在Eden区域;
  • 幸存的或者中期的对象将会从Eden区域拷贝到Survivor区域;
  • 始终存在或者长期的对象将会从Survivor拷贝到Old Generation;

生命周期来划分对象,可以消耗很短的时间和CPU做一次小的垃圾回收(GC)。原因是跟C一样,内存的释放(通过销毁对象)通过2种不同的GC实现:Young GC、Full GC。

为了检查所有的对象是否能够被销毁,Young GC会标记不能销毁的对象,经过多次标记后,对象将会被移动到老年代中。

哪儿的OutOfMemoryError

对内存结构清晰的认识同样可以帮助理解不同OutOfMemoryErrors:

Exception in thread “main”: java.lang.OutOfMemoryError: Java heap space

原因:对象不能被分配到堆内存中

Exception in thread “main”: java.lang.OutOfMemoryError: PermGen space

原因:类或者方法不能被加载到老年代。它可能出现在一个程序加载很多类的时候,比如引用了很多第三方的库;

Exception in thread “main”: java.lang.OutOfMemoryError: Requested array size exceeds VM limit

原因:创建的数组大于堆内存的空间

Exception in thread “main”: java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space?

原因:分配本地分配失败。JNI、本地库或者Java虚拟机都会从本地堆中分配内存空间。

Exception in thread “main”: java.lang.OutOfMemoryError: <reason> <stack trace>(Native method)

原因:同样是本地方法内存分配失败,只不过是JNI或者本地方法或者Java虚拟机发现;

关于OutOfMemoryError的更多信息可以查看:“Troubleshooting Guide for HotSpot VM”, Chapter 3 on “Troubleshooting on memory leaks”

 

参考链接:

分享到:
评论

相关推荐

    Java 内存模型

    Java内存模型是Java虚拟机规范中定义的一部分,它规定了Java程序中变量的读写行为,以及线程之间的交互规则。理解Java内存模型对于编写正确、高效的多线程程序至关重要。在Java 5之前,Java内存模型的描述比较模糊,...

    Java内存模型详解

    ### Java内存模型详解 #### 1. JMM简介 ##### i. 内存模型概述 Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)的一部分,用于规定程序中的各种变量(包括实例字段、静态字段和数组元素等)在多个...

    深入理解 Java 内存模型

    1. **内存层次结构**:Java 内存模型将内存分为堆内存、栈内存、方法区(在 Java 8 及以后版本中被元空间替代)和程序计数器等几个区域,其中堆存储对象实例,栈存储局部变量,方法区存储类信息,程序计数器则用于...

    java内存模型详解--非常经典

    Java内存模型(JVM Memory Model,简称JMM)是Java平台中的一个重要概念,它定义了程序中各个变量的访问规则,以及在多线程环境下的内存一致性效果。JMM主要解决的是并发环境下不同线程之间如何共享数据以及如何保证...

    java内存模型.pdf

    标题和描述中提及的知识点主要围绕Java内存模型(JMM),JVM内存结构,包括堆栈讲解,以及本机内存管理等内容。以下是对这些知识点的详细阐述: ### Java内存模型(JMM) #### JMM简介 Java内存模型(JMM)是Java虚拟机...

    Java内存模型分析与其在编程中的应用.pdf

    Java内存模型是Java平台的核心概念之一,它定义了Java程序中各种变量的访问规则以及如何在运行时分配内存区域给对象。Java内存模型的深入分析对于编写高性能的Java应用程序至关重要,本文将详细探讨Java内存模型的...

    深入理解Java内存模型.程晓明(带书签文字版).pdf

    Java 内存模型的抽象 4 重排序 6 处理器重排序与内存屏障指令 7 happens-before 10 重排序 13 数据依赖性 13 as-if-serial 语义 13 程序顺序规则 15 重排序对多线程的影响 15 顺序一致性 19 数据竞争与顺序...

    Java理论与实践:修复Java内存模型1

    Java内存模型(Java Memory Model, JMM)是Java平台中用于规范线程间通信和内存可见性的重要概念,它的目标是确保多线程环境下的正确同步。然而,原始的JMM存在一些严重的缺陷,导致了开发者在理解和实现线程安全时...

    深入理解JAVA内存模型(高清完整版)

    Java内存模型(JVM Memory Model,简称JMM)是Java平台中的一个重要概念,它定义了在多线程环境下,如何在共享内存中读写数据,以及如何保证数据的一致性和可见性。本教程《深入理解JAVA内存模型》将带你深入探讨这...

    Java内存模型知识汇总

    Java内存模型(JMM)是Java虚拟机(JVM)规范的一部分,用于定义多线程环境下共享变量的访问规则和操作的可见性。本文将对Java内存模型进行知识汇总,帮助读者更好地理解和掌握相关知识点。 首先,内存模型的概念是...

    深入理解Java内存模型(经典).rar

    Java内存模型,简称JMM(Java Memory Model),是Java虚拟机规范中定义的一个抽象概念,它描述了在多线程环境下,如何保证共享数据的正确性。深入理解JMM对于编写高效、线程安全的Java代码至关重要。 首先,我们要...

    Java内存模型描述及变量运用分析.pdf

    Java内存模型中还涉及到对象的创建和初始化过程,其中涉及到构造函数和初始化块。当一个类的对象被实例化时,JVM会调用相应的构造函数,按照声明顺序执行所有成员变量和初始化块,最终将对象的状态初始化到一个合法...

    JVM内存结构、Java内存模型、Java对象模型1

    Java内存模型(JMM)与JVM内存结构不同,它是针对多线程环境下内存访问的抽象模型。JMM确保在多线程环境下,共享变量的读写操作具有正确的顺序和可见性,通过volatile、synchronized等关键字来实现这一目标。JMM关注...

    深入java内存模型

    《深入Java内存模型》是一本面向Java开发人员的专业书籍,旨在帮助读者深入理解Java平台的内存管理和性能优化。这本书详细探讨了Java内存模型(JVM)的基础知识,以及如何利用这些知识来提升程序的效率和稳定性。...

    深入理解Java内存模型(二)共3页.pdf.zip

    8. Java内存模型与JVM内存结构的关系:虽然两者名字相似,但JMM关注的是线程间的通信和同步,而JVM内存结构则更多地涉及堆、栈、方法区等内存区域的划分。 在实际编程中,理解并合理应用Java内存模型,可以帮助我们...

Global site tag (gtag.js) - Google Analytics