- 浏览: 33585 次
- 性别:
- 来自: 天津
最新评论
一、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>
发表评论
-
JDK,JRE,JVM区别与联系
2014-08-14 19:23 617很多朋友可能跟我一 ... -
eclipse正则表达式批量查找替换
2012-07-26 13:50 1275我们经常使用一些工具进行替换操作,有些工具在替换时支持使用正则 ... -
Oracle10g JDBC ojdbc14 DATE类型hibernate查询时分秒问题(纠结困扰了半天,汗)
2012-04-16 10:46 1571一般的数据库中,DATE字段仅仅表示日期,不包括日期信息,而O ... -
java好的编码习惯
2012-03-11 09:49 835最近的机器内存又爆 ... -
HashMap原理
2012-01-13 10:46 1028Hashmap是一种非常常用的、应用广泛的数据类型,最近研究到 ... -
hibernate.jdbc.fetch_size 和 hibernate.jdbc.batch_size
2012-01-10 16:44 959hibernate.jdbc.fetch_size 和 h ... -
struts2 标签 <s:set> <s:if>
2011-12-23 10:40 1202Struts2中s:set标签和s:if标 ... -
spring中集成测试
2011-11-18 10:13 726详细讲解在Spring中进行集成测试 ... -
java 学习之路
2011-09-17 12:57 611《ThinkinginJava》。它是 ... -
spring 配置连接池
2011-09-17 12:57 1154不管通过何种持久化技术,都必须通过数据连接访问数据库,在 ... -
java 内部类的应用场景
2011-09-17 12:54 853幕后英雄的用 ... -
jdk与jre的区别
2011-09-17 12:49 702jdk与jre的区别 很多程序 ...
相关推荐
主要是JVM内存分配及简单的JVM性能调优
关于java的内存分配问题,jvm的运行原理相关资料总结
个人整理 jvm相关知识 包括内存分配机制 垃圾回收机制 垃圾收集器相关 及 垃圾收集算法
23丨如何优化JVM内存分配?.html
NULL 博文链接:https://younglibin.iteye.com/blog/1959816
1.jvm内存结构及功能概述 2.Jvm Heap 内存结构 3.Jvm 的内存分配
1.1 对象优先在Eden区分配 1.2 大对象直接进入老年代 1.3 长期存活的对象将进入老年代
JVM初始分配的内存.doc JVM初始分配的内存.doc
详细介绍了JVM 内存管理相关知识 内存空间( VM运行时数据区域) ◦ 内存结构 ◦ 内存空间 内存分配 内存回收(GC) 内存分析工具
NULL 博文链接:https://bxf12315.iteye.com/blog/1575773
jmap -heap pid可以查看应用程序堆的信息jstat可以打印元空间信息MC :分配到元空间大小MU:已使用的元空间大小 元空间是可以自己扩容的元空间:
1、JVM 内存分配图解的 Visio 工程图。 2、直接下载使用、可自行调整和修改
JVM内存段分配,Java垃圾回收调优,Heap设定
jvm的内存结构图,详细的介绍了jvm运行的模型流程,包括jvm运行的五大内存分布。通过什么是jvm什么是java编程程序的=中的三个兄弟jdk.jvm和jre的区别
主要介绍了JVM内存分配及String常用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Jvm对象内存分配理解
2019最新深入理解JVM内存结构及运行原理(JVM调优)高级核心课程视频教程下载。JVM是Java知识体系中的重要部分,对JVM底层的了解是每一位Java程序员深入Java技术领域的重要因素。本课程试图通过简单易懂的方式,系统...
JVM调优是一个系统而又复杂的过程,由于Java虚拟机自动管理内存,在大多数情况下,我们基本上不用去调整JVM内存分配,因为一些初始化参数已经可以保证应用服务正常稳定地工作。但是当有性能问题的时候该怎么去调优,...