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.程 ...
随机推荐
- java异常中throw和throws的区别
throws和throwthrows:用来声明一个方法可能产生的所有异常,不做任何处理而是将异常往上传,谁调用我我就抛给谁. 用在方法声明后面,跟的是异常类名 可以跟多个异常类名,用逗号隔开 表 ...
- 小度WiFi
这个东西真不错,详情查看: http://wifi.baidu.com 是在京东上抢购的,但是那次抢购体验做得很次:首先,只能预约一种颜色;其次,第一天抢购了,第2天就不能抢购了;第三,等抢购完了,如 ...
- 【Linux】Cent OS 虚拟机开机自启动配置
一次断电,导致实体机关机了,虚拟机也连不上去,只好手动来起来. 我想增加一下自启动,让硬件开机的时候,自动启动虚拟机: 其实是有办法的,尝试了一下,也成功了,这里简单标记下. virsh autost ...
- 动态规划之 <筷子>
描述 A 先生有很多双筷子.确切的说应该是很多根,因为筷子的长度不一,很难判断出哪两根是一双的.这天,A 先生家里来了K 个客人,A 先生留下他们吃晚饭.加上A 先生,A夫人和他们的孩子小A,共K+3 ...
- Spark机器学习(11):协同过滤算法
协同过滤(Collaborative Filtering,CF)算法是一种常用的推荐算法,它的思想就是找出相似的用户或产品,向用户推荐相似的物品,或者把物品推荐给相似的用户.怎样评价用户对商品的偏好? ...
- Gson解析第三方提供Json数据(天气预报,新闻等)
之前都是自己写后台,自己的server提供数据给client. 近期在看第三方的数据接口,訪问其它站点提供的信息.比方.我们可能自己收集的数据相当有限.可是网上提供了非常多关于天气预报.新闻.星座运势 ...
- O_DIRECT与O_SYNC区别(转)
O_DIRECT和O_SYNC是系统调用open的flag参数.通过指定open的flag参数,以特定的文件描述符打开某一文件. 这两个flag会对写盘的性能有很大的影响,因此对这两个flag做一些详 ...
- 【MySQL】MySQL视图创建、查询。
视图是指计算机数据库中的视图,是一个虚拟表.关系型数据库中的数据是由一张一张的二维关系表所组成,简单的单表查询只需要遍历一个表,而复杂的多表查询需要将多个表连接起来进行查询任务.对于复杂的查询事件,每 ...
- 【tp5】ThinkCMF5框架,配置使其支持不同终端PC/WAP/Wechat能加载不同配置和视图
1.版本 5.0.18 2.在data/conf/ 新增config.php文件,内容如下: <?php //ThinkCMF5区别不同客户端加载不同配置文件和模块.视图 $default_mo ...
- 在Asp.Net中操作PDF – iTextSharp - 操作图片
iTextSharp支持所有主流的图片格式,比如:jpg, tif, gif, bmp, png和wmf.在iTextSharp中使用Image.GetInstance()方法创建图片有很多种方式,或 ...