JVM的内存划分以及常用参数
JVM的主要划分为: 堆内存,虚拟机栈,方法区,程序计数器,本地方法栈
堆内存: 这部分区域是各个线程共享的,java的大部分对象都是储存在堆中。
1.堆在分配对象内存区域的时候可以分为两种,第一种叫做指针碰撞,这总方式在于内存区域是连续的,使用过的内存存在在一边,未使用的内存存放在另外一边,而中间是用指针来进行区分的,当我们需要创建一个新对象的时候,只需要将这个指针移动一个对象的长度即可,这种方式就相当于数据结构中的顺序存储。而第二种叫做闲置列表,这种方式不要求内存是连续的,需要维护一个列表,标记哪些部分是使用过的,那些部分是未使用过的,当我们创建新对象的时候,只需要将未使用的一块内存分配给对象即可,同时将这个信息记录到列表中去,这种方式相当于数据结构中的链式储存。
2.还需要考虑的一个问题就是因为创建对象是直接在内存中进行分配,可能会出现并发的情况,所以在创建对象的时候需要进行处理,主要的方式有采用CAS的方式或者是采用TLAB(Thread local Allocation Buffer 即为每一个线程预先分配一块区域,如果不够的话,在进行扩容),第二种方式可以采用JVM参数: -XX:-/+UseTLAB .
3.堆主要分为几个部分:年轻代和老年代。
年轻代 又分为Eden和两个survivor区,年轻代的大小可以通过-Xmnsize 进行分配,注意这里是不能大于总的堆大小的(Xms,Xmx)
我们还可以通过XX:SurvivorRatio=ratio 设置Eden区和一个s区的大小比例。对象的分配主要是在Eden区(如果没有开启TLAB),如果Eden区没有足够的空间的话,那么就会触发一次Minior GC(可以通过 -XX:+PrintGCDetails 打印GC信息),发生Minior GC的时候,对象就会被放入到s区,当s区的对象在多次的MiniorGC之后还存在的话,那么就直接进入了老年代,同时需要注意MiniorGC是分成频繁的。
老年代 指的是那些在MiniorGC存活下来的对象(也就表示这些对象经常被使用,不会频繁的被清理),如果老年代内存不足的话,那么就会发生一次Full GC,Full GC是非常影响性能的,他会停止和他相关的工作,如果遇到很大的堆内存,停留的时间可能会很长,所以需要注意。
虚拟机栈: 虚拟机栈是线程隔离的,也就是说虚拟机栈中的东西其他线程是看不到的,主要存放的有局部变量表,操作数栈,动态链接和方法出。
局部变量表存放的有基本类型(short int long float double char byte boolean),对象的引用(包括数组的),其中long double 占用了两个局部变量空间(Slot 局部变量表的容量以变量槽(Slot)为最小单位,32位虚拟机中一个Slot可以存放一个32位以内的数据类型(boolean、byte、char、short、int、float、reference和returnAddress八种),注意局部变量表存放的是方法参数和内部定义的变量。
操作数栈 是一个栈的形式,其中在方法内的计算都将压入栈(类似逆波兰)。
动态链接 表示的是对方法对常量池的引用。
方法出口 一个线程的栈是由多个栈帧组成的,一般我们在使用方法的时候都是一条调用链,也就说每一个方法就是对应一个栈帧(这也可以通过理解一般方法调用链都是先执行最后调用的方法【毕竟这是一个栈嘛】)
方法区:在Hotspot中为被称为是永久带(在JDK8已经被Metaspaces替代了),其中需要存放的是类信息,常量,静态变量以及即时编译器变异后的代码。
程序计数器:因为Java是多线程模型,所以多个线程会经常切换,那么我们就需要在切换的时候保存当前的执行位置和一些必须的变量,那么在切换回来的时候就可以继续的执行了。
本地方法栈:和虚拟机栈相似,不过这些方法不是在JVM中执行的,所以也不会占用堆内存,但是需要注意的是,需要保证操作系统留有足够的空间在支持本地方法的执行。
下面是一个理解中的JVM:

JVM常用参数
* -XmsSize(最小堆内存)
* -XmxSize(最大堆内存)
* -XmnSize(分配给年轻代)
* -XX:+PrintGCDetails 输出详细GC日志
* -XX:SurvivorRatio=ratio Eden区和survivor区的比例
* -XX:-UseTLAB 是否使用本地线程分配缓冲
* -XX:+HeapDumpOnOutOfMemoryError(在出现异常的情况下 将内存快照dump出来)
* -XssSize 栈大小
* -XX:MaxPermSize 方法区的最大值(JDK<=1.7 .8将方法区移去,增加了metaspaces)
* -XX:PermSize 方法区的大小
Java中出现OutOfMemeoryError的情况
出现这种情况可以分为两种,分别是内存溢出和内存泄露
内存溢出 出行内存溢出的原因在于内存没用分配好,需要根据具体情况进行设置,其中可能是堆内存不足,也可能是系统内存不足(本地方法栈或者是虚拟机栈不够),或者是线程数太多(线程数<( 操作系统可用内存-堆内存)/栈大小)
内存泄露: 内存泄露可能是人为的一些操作导致的,对于没有使用的对象却一直保持了到Root间的可达(可达的意思是说一个对象可以和Root之间间接后者直接有引用关系,而Root一般为:虚拟机栈中的栈帧中的局部变量表的变量,方法区静态属性引用的对象,方法区中的常量引用的对象,本地方法中引用的变量)
在生产环境中强烈的要求设置HeapDumpOnOutOfMemoryError 这样在出现问题之后能够把内存快照给dump出来(因为这些问题很难重现)。便于使用工具进行分析,进而进行解决。
参考:
1.深入理解Java虚拟机 第二章
2,栈帧、局部变量表、操作数栈 http://wangwengcn.iteye.com/blog/1622195
JVM的内存划分以及常用参数的更多相关文章
- JDK8中JVM堆内存划分
一:JVM中内存 JVM中内存通常划分为两个部分,分别为堆内存与栈内存,栈内存主要用运行线程方法 存放本地暂时变量与线程中方法运行时候须要的引用对象地址. JVM全部的对象信息都 存放在堆内存中.相比 ...
- JVM堆内存相关的启动参数:年轻代、老年代和永久代的内存分配
如果想观察JVM进程占用的堆内存,可以通过命令工具jmap或者可视化工具jvisualvm.exe.JVM这些启动参数都拥有默认值,如果想了解JVM的内存分配策略,最好手动设置这些启动参数.再通过JD ...
- Weblogic内存溢出及常用参数配置
http://www.360doc.com/content/14/0306/14/16134804_358216319.shtml 一.WebLogic内存溢出 最近访问量门户访问量突然增大, ...
- (适合入门)JVM堆内存相关的启动参数:年轻一代、岁和永久代内存分配
假设你要观察JVM进程消耗的堆内存,通过命令工具jmap或可视化工具jvisualvm.exe.JVM这些参数的默认启动值.假设你想知道JVM内存分配策略,最开始手动设置这些参数.通过JDK统计结果, ...
- Java学习笔记9---类静态成员变量的存储位置及JVM的内存划分
笔记8提到了类静态成员变量的访问方式,但静态成员变量存储在哪里呢?在网上查阅不少资料,发现好多内容都是过时的了,其中主流观点是静态成员变量存放在方法区.JDK8之前,静态成员变量确实存放在方法区:但J ...
- JVM的内存划分
1.栈内存:栈内存主要是用来运行函数的,在函数中定义的所有变量,都会在这个内存开辟空间. 在栈内存中定义的变量,不初始化,是不能直接使用的. 注意:所有的函数都必须在栈内存中运行. 而jvm只会运行处 ...
- JVM Java 内存区域透彻分析(转)
出处: Java 内存区域透彻分析 Java8内存模型—永久代(PermGen)和元空间(Metaspace) 这篇文章主要介绍Java内存区域,也是作为Java虚拟机的一些最基本的知识,理解了这 ...
- jvm的内存分配总结
最近看了周志明版本的<深入理解Java虚拟机>第一版和第二版,写的很好,收获很多,此处总结一下. jvm中内存划分: 如上图,一共分为五块,其中: 线程共享区域为: 1.java堆 ...
- 第1篇--基于jdk7和jdk8分析 JVM的内存区域
基于jdk7和jdk8分析 JVM的内存区域 目录前言1.什么是JVM2.JRE/JDK/JVM是什么关系3.JVM执行程序的过程4. JVM的生命周期5.JVM垃圾回收一.运行时数据区的组成1.程 ...
随机推荐
- AngularJS中监视Scope变量以及外部调用Scope方法
在AngularJS中,有时候需要监视Scope中的某个变量,因为变量的改变会影响一些界面元素的显示.有时,也希望通过jQuery调用Scope的某个方法. 比如以下场景: <div> & ...
- raw_socket(原始套接字)以及普通socket使用终极总结
一.传输层socket(四层socket,普通socket) 可参考本人以下博客: Windows Socket编程之UDP实现大文件的传输:http://blog.csdn.net/luchen ...
- 使用lightProbe来模拟动态物体的照明shader
VertexLit path中读取lightProbe烘焙信息: Shader "VertexLitProbe" { Properties { _MainTex ("Ba ...
- SqlSession介绍
SqlSession是MyBatis的关键对象,是执行持久化操作的对象,类似于JDBC中的Connection.它是应用程序与持久存储层之间执行交互操作的一个单线程对象,也是MyBatis执行持久化操 ...
- 求标准分sql
if object_id('tempdb..#tempTable') is not null Begin drop table #tempTable End [校区],[学年],[考试年级],[考试类 ...
- hihocoder第238周:杨氏矩阵的个数
题目链接 问题描述 给定一个N行M列的矩阵,往里面填入$1-N\times M$个数字,使得这个矩阵每行.每列都满足递增.问:有多少种填法? 问题分析 这个问题很难,如果能够直接想到,那就是天才了. ...
- JAVA JSON解析:类XPATH解析JSON
目前JAVA解析JSON的方式有很多种,json-lib啊,GJSON啊,等等都可以解析,但通常是将JSON转换为对象或者是LIST或者是MAP,对于我们测试人员来说,其实我们并不需要里面的全部信息, ...
- Django Web开发学习笔记(3)
1.创建一个简单视图 这章是按照DgangoBook的说明.在我们创建的工程目录下面DjangoE_1(这是我为自己的工程命名的名字)新建一个view.py的文件,并在该文件下添加如下代码 from ...
- sklearn:Python语言开发的通用机器学习库
引言:深入理解机器学习并全然看懂sklearn文档,须要较深厚的理论基础.可是.要将sklearn应用于实际的项目中,仅仅须要对机器学习理论有一个主要的掌握,就能够直接调用其API来完毕各种机器学习问 ...
- Android 组件系列-----Activity初步
在上篇博文讲解了Android的Activity这个组件的启动流程后,接下来我们就来看看我们的Activity与我们的布局文件的关系吧 我们先来看看一个最简单的布局文件的内容: <Relativ ...