在工作中总会时不时与JVM打交道,尤其是在做性能调优或是看见OOM时,就需要对jvm启动参数做些调整,而我总是头疼于那些参数的含义,特记之。
引用博文:
The Java Memory Architecture
http://blog.codecentric.de/en/2010/01/the-java-memory-architecture-1-act/
JVM内存管理总结 http://blog.csdn.net/lengyuhong/article/details/5953544
JVM内存管理-深入垃圾收集器与内存分配策略
http://www.iteye.com/topic/802638
JVM内存管理-深入Java内存区域与OOM http://www.iteye.com/topic/802573
图解JVM内存模型 http://longdick.iteye.com/blog/473866
图解JVM在内存中申请对象及垃圾回收流程 http://longdick.iteye.com/blog/468368
一次Java垃圾收集调优实战 http://www.iteye.com/topic/212967
JVM参数表 http://blogs.oracle.com/watt/resource/jvm-options-list.html
JVM的内部结构如下图:
JVM主要包括两个子系统和两个组件:
1. 两个子系统分别是Class loader子系统和Execution engine(执行引擎) 子系统;
1.1 Class loader子系统的作用:根据给定的全限定名类名(如 java.lang.Object)来装载class文件的内容到 Runtime data area中的method area(方法区域)。Java程序员可以extends java.lang.ClassLoader类来写自己的Class loader。
1.2 Execution engine子系统的作用:执行classes中的指令。任何JVM specification实现(JDK)的核心都是Execution engine,不同的JDK例如Sun 的JDK 和IBM的JDK好坏主要就取决于他们各自实现的Execution engine的好坏。
2. 两个组件分别是Runtime data area (运行时数据区域)组件和Native interface(本地接口)组件。
2.1 Native interface组件:与native libraries交互,是其它编程语言交互的接口。当调用native方法的时候,就进入了一个全新的并且不再受虚拟机限制的世界,所以也很容易出现JVM无法控制的native heap OutOfMemory。
2.2 Runtime Data Area组件:这就是我们常说的JVM的内存了。它主要分为五个部分——
1、Heap (堆):一个Java虚拟实例中只存在一个堆空间,Java堆是被所有线程共享的,在虚拟机启动时创建。Java堆的唯一目的就是存放对象实例,绝大部分的对象实例都在这里分配。Java堆内还有更细致的划分:新生代、老年代,再细致一点的:eden、from survivor、to survivor,甚至更细粒度的本地线程分配缓冲(TLAB)等,无论对Java堆如何划分,目的都是为了更好的回收内存,或者更快的分配内存。
Java堆可以处于物理上不连续的内存空间,它逻辑上是连续的即可,就像我们的磁盘空间一样。实现时可以选择实现成固定大小的,也可以是可扩展的,不过当前所有商业的虚拟机都是按照可扩展来实现的(通过-Xmx和-Xms控制)。如果在堆中无法分配内存,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。
2、Method Area(方法区域):被装载的class的信息存储在Method area的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件内容并把它传输到虚拟机中。叫“方法区”可能认识它的人还不太多,如果叫永久代(Permanent Generation)它的粉丝也许就多了。它还有个别名叫 做Non-Heap(非堆)。
方法区中存放了每个Class的结构信息,包括常量池、字段描述、方法描述等等。Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量表(constant_pool table),用于存放编译期已可知的常量,这部分内容将在类加载后进入方法区(永久代)存放。但是Java语言并不要求常量一定只有编译期预置入Class的常量表的内容才能进入方法区常量池,运行期间也可将新内容放入常量池(最典型的String.intern()方法)。
运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法在申请到内存时会抛出OutOfMemoryError异常。
3、Java Stack(java的栈):虚拟机只会直接对Java stack执行两种操作:以帧为单位的压栈或出栈。栈描述的是Java方法调用的内存模型:每个方法被执行的时候,都会同时创建一个帧(Frame)用于存储本地变量表、操作栈、动态链接、方法出入口等信息。每一个方法的调用至完成,就意味着一个帧在VM栈中的入栈至出栈的过程。
4、Program Counter(程序计数器):每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的饿地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。
5、Native method stack(本地方法栈):保存native方法进入区域的地址.
以上五部分只有Heap 和Method Area是被所有线程的共享使用的;而Java stack, Program counter 和Native method stack是以线程为粒度的,每个线程独自拥有自己的部分。
此外还有本机直接内存的管理(Direct Memory) -- 直接内存并不是虚拟机运行时数据区的一部分,它根本就是本机内存而不是VM直接管理的区域。
显然本机直接内存的分配不会受到Java堆大小的限制,但是即然是内存那肯定还是要受到本机物理内存(包括SWAP区或者Windows虚拟内存)的限制的,一般服务器管理员配置JVM参数时,会根据实际内存设置-Xmx等参数信息,但经常忽略掉直接内存,使得各个内存区域总和大于物理内存限制(包括物理的和操作系统级的限制),而导致动态扩展时出现OutOfMemoryError异常。
JVM内存模型实例以及参数对应:
Model-1
|
Model-2
|
Exception
|
JVM Options
|
Method Area
|
Perm
|
java.lang.OutOfMemoryError: PermGen space
|
-XX:PermSize=<value>
-XX:MaxPermSize=<value>
|
Heap
|
Young Tenured
|
java.lang.OutOfMemoryError: Java heap space
…
|
-Xms<size>
-Xmx<size>
-Xmn<size>
-XX:newSize
-XX:MaxNewSize
-XX:NewRatio=<value>
-XX:SurvivorRatio=<value>
…
|
Thread-1…N
|
NULL
|
java.lang.StackOverflowError
…
|
-Xss<size>
…
|
*Memory Size of Runtime JVM
= Heap + Perm + Sum(Thread-1...N)
- 大小: 15.4 KB
- 大小: 67.5 KB
- 大小: 23.6 KB
- 大小: 11.6 KB
分享到:
相关推荐
通过观看"jvm视频",你可以直观地了解这些概念,并通过"jvm笔记"加深理解和记忆。理论学习后,实践操作是巩固知识的关键,尝试在实际项目中应用这些知识,解决性能问题,优化JVM配置,将使你对JVM的理解更加深入。
#### 一、JVM内存模型概览 JVM(Java虚拟机)内存模型主要由以下几个部分组成:程序计数器、Java虚拟机栈、本地方法栈、Java堆以及方法区(在JDK 8之后称为元空间)。下面将对这几个部分进行详细介绍。 #### 二、...
### JVM学习笔记 #### JVM内存模型 (JMM) JVM内存模型主要分为以下几个部分: - **Java堆**:这是所有线程共享的一块区域,在虚拟机启动时创建。主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 - *...
1:JVM内存模型:类加载机制【转载、验证、准备、解析、初始化】+类装载器【装载器分类、加载原则】+运行时数据区【方法区、堆、虚拟机栈、本地方法栈、程序计数器】。 2:垃圾回收:垃圾确定【引用计数法、可达性分析...
1. **JVM内存模型** - **方法区**:也称为“永久代”,存储虚拟机加载的类信息、常量、静态变量等,是线程共享的区域。在Java 8之后,这部分被元空间(Metaspace)取代。 - **运行时常量池**:是方法区的一部分,...
它用来描述Java方法执行的内存模型,每个方法被执行时都会创建一个栈帧来存储局部变量表、操作数栈、动态链接、方法出口等信息。方法执行过程即为栈帧的入栈和出栈过程。 - **局部变量表**: 存储方法参数和方法内部...
【描述】"ImagesForJVM——JVM笔记图片" 暗示这些图片可能是教学或学习笔记的一部分,旨在通过视觉化的方式解释JVM的关键概念,如内存模型、类加载机制、垃圾收集以及性能优化等方面。 【标签】"java" 明确了这些...
这份资料出自B站上的【狂神说Java】系列教程,为快速入门JVM提供了详实的笔记。以下是根据这些资源可能包含的一些关键知识点的详细解析: 1. **JVM概述**: - JVM是Java平台的核心组成部分,它是一个运行Java字节...
1. **早期版本**:JVM的首个公开版本是1.0,那时的JVM执行效率较低,主要用于小型设备和网络应用。 2. **JVM优化**:1998年的JVM 1.1版本引入了JNI(Java Native Interface),使得Java能够调用本地库。随后的1.2...
1. 类装载器(ClassLoader):负责加载.class文件,将字节码内容解析并存储到内存中,同时根据双亲委派模型进行类的加载。类装载器分为启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader...
JVM性学习笔记-基本原理,内存模型,JVM参数设置,类加载器原理,JDK自带工具
### JVM学习笔记(一) #### 一、JVM概述与工具使用 JVM(Java Virtual Machine)是Java语言的核心组成部分之一,它为Java程序提供了一个跨平台的运行环境。本篇学习笔记主要介绍如何利用一系列工具来查看和监控JVM...
3. 内存模型:JVM内存分为堆、栈、方法区、本地方法栈、程序计数器等几部分。其中,堆是对象存储的地方,栈处理方法调用,方法区存储类信息。 4. 垃圾收集:JVM的自动内存管理关键在于垃圾收集,包括可达性分析、...
本学习笔记旨在全面解析JVM的工作原理,涵盖内存管理、类加载机制、垃圾收集、性能调优等多个关键领域,帮助读者从基础到深入地掌握JVM。 1. **JVM结构与运行过程** - JVM由类装载器、运行时数据区、执行引擎、...
《JVM内存管理学习笔记》 在Java世界中,JVM(Java Virtual Machine)是运行所有Java应用程序的核心。深入理解JVM内存管理对于优化程序性能、预防和解决内存泄漏问题至关重要。本文将从JVM内存模型、内存区域划分、...
java初学者了解jvm相关知识增强
随着技术的进步,JVM实现了从最初的简单解释器到现在的混合型执行模型,如Hotspot JVM,它结合了即时编译和解释执行的优点。 JVM的实现有多种,如Oracle的Hotspot、IBM的J9等,它们各自具有不同的特性和优化策略。...
《JVM学习笔记与调优实战》是一本深入探讨Java虚拟机(JVM)的书籍,旨在帮助读者理解和掌握JVM的工作原理以及如何进行性能优化。在这个项目中,作者不仅分享了理论知识,还提供了实战调优的经验。下面将详细讨论JVM...
4. **内存监控**:内存监控是通过Java管理扩展API(JMX)提供的Runtime/MemoryMXBean和MemoryPoolMXBean来实现,可以监控整个堆内存和各个内存池的使用情况。 接着,文档介绍了堆内存的监控和设置参数: 1. **堆...