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的内存划分以及常用参数的更多相关文章

  1. JDK8中JVM堆内存划分

    一:JVM中内存 JVM中内存通常划分为两个部分,分别为堆内存与栈内存,栈内存主要用运行线程方法 存放本地暂时变量与线程中方法运行时候须要的引用对象地址. JVM全部的对象信息都 存放在堆内存中.相比 ...

  2. JVM堆内存相关的启动参数:年轻代、老年代和永久代的内存分配

    如果想观察JVM进程占用的堆内存,可以通过命令工具jmap或者可视化工具jvisualvm.exe.JVM这些启动参数都拥有默认值,如果想了解JVM的内存分配策略,最好手动设置这些启动参数.再通过JD ...

  3. Weblogic内存溢出及常用参数配置

        http://www.360doc.com/content/14/0306/14/16134804_358216319.shtml 一.WebLogic内存溢出 最近访问量门户访问量突然增大, ...

  4. (适合入门)JVM堆内存相关的启动参数:年轻一代、岁和永久代内存分配

    假设你要观察JVM进程消耗的堆内存,通过命令工具jmap或可视化工具jvisualvm.exe.JVM这些参数的默认启动值.假设你想知道JVM内存分配策略,最开始手动设置这些参数.通过JDK统计结果, ...

  5. Java学习笔记9---类静态成员变量的存储位置及JVM的内存划分

    笔记8提到了类静态成员变量的访问方式,但静态成员变量存储在哪里呢?在网上查阅不少资料,发现好多内容都是过时的了,其中主流观点是静态成员变量存放在方法区.JDK8之前,静态成员变量确实存放在方法区:但J ...

  6. JVM的内存划分

    1.栈内存:栈内存主要是用来运行函数的,在函数中定义的所有变量,都会在这个内存开辟空间. 在栈内存中定义的变量,不初始化,是不能直接使用的. 注意:所有的函数都必须在栈内存中运行. 而jvm只会运行处 ...

  7. JVM Java 内存区域透彻分析(转)

    出处:  Java 内存区域透彻分析  Java8内存模型—永久代(PermGen)和元空间(Metaspace) 这篇文章主要介绍Java内存区域,也是作为Java虚拟机的一些最基本的知识,理解了这 ...

  8. jvm的内存分配总结

    最近看了周志明版本的<深入理解Java虚拟机>第一版和第二版,写的很好,收获很多,此处总结一下.   jvm中内存划分:   如上图,一共分为五块,其中: 线程共享区域为: 1.java堆 ...

  9. 第1篇--基于jdk7和jdk8分析 JVM的内存区域

     基于jdk7和jdk8分析 JVM的内存区域 目录前言1.什么是JVM2.JRE/JDK/JVM是什么关系3.JVM执行程序的过程4. JVM的生命周期5.JVM垃圾回收一.运行时数据区的组成1.程 ...

随机推荐

  1. copy unicode HTML to clipboard

    How to copy unicode HTML code to the clipboard in html format, so it can be pasted into Writer, Word ...

  2. Spring boot设置文件上传大小限制

    原文:https://blog.csdn.net/lizhangyong1989/article/details/78586421 Spring boot1.0版本的application.prope ...

  3. C#编程(八十三)---------- 程序集的含义

    程序集的含义 一.程序集是包含一个或多个类型定义文件和资源文件的集合.它允许我们分析可重用类型的逻辑表示和物理表示. 相当于你定义了一个项目XXProject,项目存在很多文件(类,窗体,接口,资源等 ...

  4. MDX Cookbook 01 - Skipping Axis 合理使用空的 SET 集合获取全部层次结构成员

    假设我们只想显示一些与数据没有任何关联的维度成员信息,并且希望它们能够以行集的形式来显示,那么在 MDX 中就应该直接显示 ROWS  AXIS (1) 并且忽略掉 COLUMNS AXIS(0).比 ...

  5. PL/SQL学习笔记之触发器

    一:触发器响应的事件 数据库操作(DML)语句(DELETE,INSERT,UPDATE) 数据库定义(DDL)语句(CREATE,ALTER或DROP) 数据库操作(SERVERERROR,登录,注 ...

  6. 初始cfx开发webservice, 简单实例应用

    项目结构图: 步骤一: 添加maven 依赖包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

  7. 12C -- DDL日志

    DDL日志和alert日志有相似的格式和行为.但是只包含DDL语句日志.oracle只是为数据库组件提供DDL日志,且需要将参数enable_ddl_logging设置为true. 在DDL日志中,每 ...

  8. CentOS7中systemctl的使用与CentOS6中service的区别

    https://blog.csdn.net/u012834750/article/details/80501440 从CentOS 7.x开始,CentOS开始使用systemd服务来代替daemon ...

  9. SQL SERVER 行列转换(动态)

    行转列测试数据: --测试数据 if not object_id(N'Tempdb..#T') is null drop table #T Go Create table #T([Name] nvar ...

  10. 在Repeater中使用DropDownList的方法

    在Repeater中使用DropDownList的方法 以下代码并不完整,只记录了关键的方法 aspx代码中 假设这是一个用户管理的系统的模型,有一个下拉菜单来操作用户状态 <asp:Repea ...