原文链接 译文链接 作者:Tai Truong 译者:Jaxon
所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?
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)。
堆内存存放对象以及数组的数据,方法区存放类的信息(包括类名、方法、字段)、静态变量、编译器编译后的代码,本地区包含线程栈、本地方法栈等存放线程
方法区有时被称为持久代(PermGen)。
所有的对象在实例化后的整个运行周期内,都被存放在堆内存中。堆内存又被划分成不同的部分:伊甸区(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 |
} |
这段程序的数据在内存中的存放如下:
通过JConsole工具可以查看运行中的Java程序(比如Eclipse)的一些信息:堆内存的分配,线程的数量以及加载的类的个数;
这里有一份极好的白皮书:Memory Management in the Java HotSpot Virtual Machine。它描述了垃圾回收(GC)触发的内存自动管理。Java的内存结构包含如下部分:
堆内存
堆内存同样被划分成了多个区域:
- 包含伊甸(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”
参考链接:
- Provides Java HotSpot information about VM Options and environment variables
-
Troubleshooting Guide for HotSpot VM
An exhaustive guide for memory leaks, system crashes, hangings, loops, signal and exception handling. -
Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning
Ergonomics and tuning goals, generations sizing using VM arguments. -
Thanks for the memory – Understanding how the JVM uses native memory on Windows and Linux
Explains how the memory in the JVM like the heap is memory into the RAM on different operating systems and CPUs (32/64bit). -
Java Micro Edition – Tuning
Describes runtime options to adjust performance in the Java ME edition. It also illustrates the compilation of bytecode into native code. - Summary of Sun’s document “Tuning Garbage collection with the 1.4.2 Hotspot JVM”.
- Discussion about where references and objects are stored in the JVM.
相关推荐
Java内存模型详解,JVM结构..
Java 内存模型的抽象 4 重排序 6 处理器重排序与内存屏障指令 7 happens-before 10 重排序 13 数据依赖性 13 as-if-serial 语义 13 程序顺序规则 15 重排序对多线程的影响 15 顺序一致性 19 数据竞争与顺序...
Java内存模型的抽象 重排序 处理器重排序与内存屏障指令 happens-before 重排序 数据依赖性 as-if-serial 语义 程序顺序规则 重排序对多线程的影响 顺序一致性 数据竞争与顺序一致性保证 顺序一致性内存模型 同步...
一套完整介绍java内存模型和内存结构的文档
Java内存结构: 深入理解Java内存模型一基础并发编程模型的分类Java内存模型的抽象重排序处理器重排序与内存屏障指令happens-before深入理解Java内存模型二重排序数据依赖性..
简略辨析JVM内存结构、Java内存模型、Java对象模型三个概念的异同 说明Java内存模型概念和核心内容 针对重排序说一说重排序的例子,重排序的好处 着重说一说可见性,说一说JVM内存的抽象、hanpens
显式内存模型的好处显式内存模型的好处像 C 和 C++ 这些语言就没有显示的内存模型 —— 但 C 语言程序继承了执行程序处理器的内存模型(尽管一个给定体系结构
JVM内存结构Java 代码是要运行在虚拟机上的,而虚拟机在执行 Java 程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途。如果
1、以上是Java虚拟机规范,不同的虚拟机实现会各有不同,但是一般会遵守规范 2、规范中定义的方法区,只是一种概念上的区域,并说明了其应该具有什么功能 3、不同
1、以上是Java虚拟机规范,不同的虚拟机实现会各有不同,但是一般会遵守规范 2、规范中定义的方法区,只是一种概念上的区域,并说明了其应该具有什么功能 3、不同
java进行必备书籍,高清版。带目录结构。方便阅读,书中内容讲的透彻
但是初学者往往深陷Java语言的内存存储结构模型,大量复杂的设计模型使其很难对所学知识进行融会贯通。李若亮老师带你深入剖析Java编程中所内存涉及的方方面面,从JVM的内存申请,到Java语言的内存加载以及Java语言...
在说Java内存模型之前,我们先说一下Java的内存结构,也就是运行时的数据区域:Java虚拟机在执行Java程序的过程中,会把它管理的内存划分为几个不同的数据区域,这些区域都有各自的用途、创建时间、销毁时间
非常清楚的描述java内存结构,对并发编程有很好的帮助。
JVM,虚拟机结构,java,内存结构
主要为大家讲解JVM内存模型|内存结构|内存屏障,他们的概念,有什么关联以及各种的功能
此文对于java初学者,想了解清楚java内存结构的童鞋,很有参考价值
基于数据结构与简化内存模型的Java集合教学方法研究.pdf
基于数据结构与简化内存模型的Java集合教学方法研究