本文将以开发者角度对JVM相关工作原理进行介绍,我会持续更新,如果大家发现不对的地方,渴望能不吝赐教
。
一、JVM简介
JVM是Java Virtual
Machine(Java虚拟机)的缩写,Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java
虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。JVM
也有自己的相关规范,使得第三方可以开发出自己的JVM,比如IBMJVM,MSJVM,HOTSPOT JVM(SUN)。本文是参考HOTSPOT
JVM进行介绍。
二、JVM内存结构
JVM内存框架图
注: 上图的序号是从左向右进行标记,序号顺序不代表逻辑关系
下面我们将按逻辑关系进行介绍
1 JVM Process Heap
32位OS:最多约2GB
64位OS:更多。
2 Java Object Heap(JAVA Heap)
通常被称为 JVM heap ,容易和 JVM process Heap混淆,它是用来存储java OBject的如:
Object的实例和 Object的基本数据及引用。
-XX:MinHeapFreeRatio=
Default is 40 (40%)
-XX:MaxHeapFreeRatio=
Default 70%
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小
于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、
-Xmx相等以避免在每次GC后调整堆的大小。
3、Young Generation
所有新创建的Object 都将会存储在这里。
配置方式 :
-Xmn – not preferred (fixed value)
-XX:NewRatio=<value> - preferred
(dynamic)
官方推荐的配置是新生代(Young Generation)占整个Java Object Heap内存的33%
4、Eden Space
新的Object总是创建在Eden Space。
5、Old Generation
如果Young Generation的数据在一次或多次GC后存活下来,那么将被转移到 OldGeneration。
6、 Survivor Spaces
GC时,Eden中活的对象复制到surivivor spaces ,当对象达到最打值(老化)时,被送到Old Generation
10、Tenured Space
5MB min 44MB max (default)
这就是传说中的老年代,官方给的解释就是:
pool containing objects that have existed for some time in the survivor space.
11、Everything else
这其实就是我们常常见到的 no-heap
12、Permanent Space
4MB initial , 63MB max
存储class的函数及其他的meta Data.
配置方式:
-XX:PermSize=<value> (initial)
-XX:MaxPermSize=<value> (max)
13、Code Generation
转换byte code 为 native code.
基本不会导致内存异常。
如果该操作没有足够的空间,JVM可能会导致崩溃。
14、Socket Buffers
包括两部分:1:Receive buffer ~37k 2:Send buffer ~25k
需要在JAVA代码中来控制他,所以在外部无法配置。
他可能导致的异常:IOException: Too many open files (for
example)
15、 Threaded JVM Stacks
jvm stacks:
jvm stack: frame data 、 operand stack ...
Thread Stacks:
表示各个Thread所分配的空间。
默认至取决于 OS/JVM
线程数增加,Thread Stacks则增大。
配置: –Xss
异常:java.lang.OutOfMemoryError:
unable to create new native thread
如果-Xss配置的太小,会引起
java.lang.StackOverflowError
16、Direct Memory Space
他可以让开发人员映射内存到java Object Heap外。
配置: XX:MaxDirectMemorySize=<value>
17、JNI Code 、
JNI code本身使用的内存非常小。
19、JNI allocate memory
JNI 程序本身也需要分配内存。
18、Garbage Collection
其实GC也是需要内存的,gc线程的消耗以及存放GC所缓存的信息。
这里简单介绍下GC的历史:
GC始于 1959 – LISP语言
他的初衷:
1、 自动内存清理
2、 让开发变得简单
3、 让debug更方便
Gc的过程
1、锁(Lock it down)
所有对象在GC时会被锁定,以保证他们不会变化。
2、标记(Mark)
遍历所有对象,标记 不可到达阶段的对象(unreachable)为 垃圾(需要回收)
3、清理(Sweep)
删除所有被标记对象
清理内存
GC在早及的JAVA版本中的问题
1、GC不能很好的协调。
2、只有一个算法。
3、标记(Mark)、清理(Sweep)需要扫描整个Heap,需要花费很久的时间。当然该时间取决与堆的大小。所以人们发明了永久性空间(Permanent Space)
GC工作原理:
Eden——所有新创建的对象都被放置在这里。
Survivor——当Eden区空间不足时,会将其中依旧存活的对象拷贝到两块Survivor区域(FromSpace和
ToSpace)中的一个,如果此时这个Survivor区域也空间不足,则将该块区域中存活的对象拷贝到另一块区域中。
注意,总有一个Survivor区域是空的。
对Young Generation的垃圾回收叫minor GC,通常很多的对象都活不过一次GC。
Old Generation——但一个Survivor区域满了的时候,会将该区域中已经历一定次数GC而依旧存活的对象放到Old
Generation中。如果Old Generation也满了,那就要Full GC了。Full GC很耗性能,当Full
GC进行时,应用程序会暂停。由于大部分对象都活不过一次GC,所以如果服务器上频繁的发生Full
GC,就要关注下是不是出问题了。
三、引起的异常
java.lang.OutOfMemoryError: Java heap space
原因:Heap内存溢出,意味着Young和Old generation的内存不够。
解决:调整java启动参数 -Xms -Xmx 来增加Heap内存。
java.lang.OutOfMemoryError: unable to create new native thread
原因:Stack空间不足以创建额外的线程,要么是创建的线程过多,要么是Stack空间确实小了。
解决:由于JVM没有提供参数设置总的stack空间大小,但可以设置单个线程栈的大小;而系统的用户空间一共是3G,除了Text/Data/BSS
/MemoryMapping几个段之外,Heap和Stack空间的总量有限,是此消彼长的。因此遇到这个错误,可以通过两个途径解决:1.通过
-Xss启动参数减少单个线程栈大小,这样便能开更多线程(当然不能太小,太小会出现StackOverflowError);2.通过-Xms
-Xmx 两参数减少Heap大小,将内存让给Stack(前提是保证Heap空间够用)。
java.lang.OutOfMemoryError: PermGen space
原因:Permanent Generation空间不足,不能加载额外的类。
解决:调整-XX:PermSize= -XX:MaxPermSize= 两个参数来增大PermGen内存。一般情况下,这两个参数不要手动设置,只要设置-Xmx足够大即可,JVM会自行选择合适的PermGen大小。
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
原因:这个错误比较少见(试着new一个长度1亿的数组看看),同样是由于Heap空间不足。如果需要new一个如此之大的数组,程序逻辑多半是不合理的。
解决:修改程序逻辑吧。或者也可以通过-Xmx来增大堆内存。
在GC花费了大量时间,却仅回收了少量内存时,也会报出OutOfMemoryError
,我只遇到过一两次。当使用-XX:+UseParallelGC或-XX:+UseConcMarkSweepGC收集器时,在上述情况下会报错,在HotSpot GC Turning文档
上有说明:
The parallel(concurrent) collector will throw an OutOfMemoryError if too
much time is being spent in garbage collection: if more than 98% of the
total time is spent in garbage collection and less than 2% of the heap
is recovered, an OutOfMemoryError will be thrown.
对这个问题,一是需要进行GC turning,二是需要优化程序逻辑。
java.lang.StackOverflowError
原因:这也内存溢出错误的一种,即线程栈的溢出,要么是方法调用层次过多(比如存在无限递归调用),要么是线程栈太小。
解决:优化程序设计,减少方法调用层次;调整-Xss参数增加线程栈大小。
IOException: Too many open files
原因: 这个是由于TCP connections 的buffer 大小不够用了。
java.lang.OutOfMemoryError:Direct buffer memory
解决:调整 -XX:MaxDirectMemorySize=<value>
参考文献:
http://download.oracle.com/javase/1.5.0/docs/guide/management/jconsole.html
http://cs.nyu.edu/courses/fall02/V22.0201-001/jvm5.html
http://hi.baidu.com/liwei_8/blog/item/b8e6bfdbd445967cd1164e64.html
http://blog.csdn.net/peart_boy/article/details/1313413
分享到:
相关推荐
本文将深入探讨JVM的工作原理及其内存模型,帮助你理解Java程序是如何在JVM上运行的。 首先,JVM的内存模型是Java性能优化的关键,它主要分为以下几个区域: 1. **堆内存(Heap Memory)**:这是所有线程共享的一...
本篇文章将深入探讨JVM的生命周期、体系结构、类加载机制、内存区域以及垃圾收集。 首先,JVM的生命周期与Java程序紧密关联。每当运行一个Java程序时,就会创建一个JVM实例。这个实例在程序执行期间存在,直到程序...
本篇文章将详细探讨JVM中的主要内存区域及其作用。 1. **程序计数器(Program Counter Register)** 每个线程都有自己的程序计数器,用于存储当前线程正在执行的字节码的指令地址。当线程执行方法时,这个计数器会...
标题《JVM系列之性能调优参考手册(实践篇)》涉及的知识点主要集中在Java虚拟机(JVM)性能调优的实践操作。JVM作为Java程序运行的基础环境,对程序性能有着决定性影响。本手册的目的是指导开发者如何对JVM进行性能...
本篇文章将深入探讨JVM的各个方面,包括其工作原理、内存模型、垃圾收集以及性能优化。 一、JVM工作原理 Java源代码经过编译器转化为字节码,这些字节码文件以`.class`结尾。JVM在运行时加载这些字节码,然后解释...
本篇文章将从JVM的结构、内存模型、类加载机制以及垃圾收集等方面,帮助初学者快速入门JVM。 一、JVM结构 JVM主要由以下几个部分组成: 1. **类装载器(ClassLoader)**:负责加载.class文件,解析字节码并将其转换...
在高级篇和优化篇中,虽然没有提供具体的内容,我们可以推断出,高级篇可能包含了对JVM更深层次的探讨,例如JVM内存模型的高级细节、类加载器的深入讨论、即时编译器(JIT)的工作原理等。而优化篇可能会涵盖JVM性能...
总的来说,了解JVM的工作原理、类文件的结构以及编译过程对于Java开发者来说至关重要,因为这能帮助我们更好地优化代码、理解和解决问题,从而提高程序的运行效率和稳定性。通过学习这些知识,我们可以深入探究Java...
本篇文章将围绕JVM的内存模型、垃圾收集机制以及G1 GC的特性进行详细的阐述。 首先,JVM的内存模型包括堆内存和非堆内存两大部分。堆内存主要分为年轻代(Young Generation)、老年代(Tenured Generation或Old ...
本篇文章将依据标题和描述,深入探讨JVM内存优化的相关知识点。 1. **JVM内存结构** JVM内存主要分为堆内存(Heap)、方法区(Method Area)、虚拟机栈(JVM Stack)、本地方法栈(Native Method Stack)和程序...
在对Java虚拟机(JVM)进行调优的过程中,我们首先需要理解JVM内存的工作原理以及各个内存区域的作用。JVM内存管理是整个Java应用程序性能优化的重要部分,它涉及对内存的分配、使用和回收的精细控制。 JVM内存可以...
《深入理解JVM & G1 GC》这篇文章和相关压缩包文件主要聚焦于Java虚拟机(JVM)的内存管理,特别是垃圾收集器(GC)的优化,特别是G1(Garbage-First)垃圾收集器的深度解析。下面将详细阐述JVM、GC的基本概念,...
原理篇》是一本针对Java程序员的技术面试用书,它详尽地总结了Java面试中常见的核心技术知识点,包括但不限于JVM原理、多线程编程、数据结构与算法、分布式系统设计等。在IT行业求职竞争激烈的背景下,本书为读者...
Java虚拟机(JVM)是Java程序运行的核心,...总结来说,这篇JVM学习笔记涵盖了对象声明、内存分配的方法以及虚拟内存的基本原理。理解这些概念对于深入理解Java程序的运行机制、性能优化以及解决内存相关问题至关重要。
本教程旨在通过96个章节的内容,帮助读者从零开始掌握JVM的核心原理及其实战技巧。 #### 二、基础知识篇 1. **Java语言简介** - Java是一种面向对象的编程语言,由Sun Microsystems公司于1995年发布。 - Java...
总的来说,这篇笔记深入介绍了JVM的内存管理,特别是垃圾收集机制,提供了从理论到实践的全面理解,对于Java开发者优化应用性能和理解JVM内部运作具有重要意义。通过掌握GC的触发时机、日志分析和优化策略,开发者...
### 深入解析 JVM 内存区域 #### 一、Java内存区域概述 Java虚拟机(JVM)作为Java程序的运行环境,负责管理和分配内存...理解这些区域对于深入学习JVM原理至关重要,也有助于开发者编写更加高效和可靠的Java应用程序。
本篇文章将详细探讨JVM的工作原理,并提供一些有效的性能优化策略。 首先,JVM的内存结构分为堆、栈、方法区、程序计数器、本地方法栈等几个关键区域。堆是所有对象实例的存储区域,而栈则用于存储方法调用时的局部...
JVM的内存模型也是理解其工作原理的关键。它分为堆内存、栈内存、方法区(在Java 8及以后版本中称为元空间)以及程序计数器、虚拟机栈等区域。每个线程都有自己独立的虚拟机栈和程序计数器,而堆内存和方法区是所有...