文档章节

JVM内存管理和垃圾回收

纳兰清风
 纳兰清风
发布于 2016/04/01 15:35
字数 1364
阅读 282
收藏 5

行业解决方案、产品招募中!想赚钱就来传!>>>

JVM内存管理和垃圾回收

 

JVM内存模型其实就是JVM在运行程序时的一个内存分布情况,主要分一下几个区域:

1.PC寄存器:

    用于存储每个线程下一步将执行的JVM指令,native方法则PC寄存器中不存储任何信息。

 

2.JVM栈:

    JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:boolean,char,byte,short,int,long,float,double)部分的返回结果以及Stack Frame,非基本类型的对象在JVM栈上仅存放一个指向堆上的地址。

 

3.JVM堆:

    它是JVM用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配。我们常说的GC内存回收就是这部分内存。堆空间为新生代和老年代。

 

3.1新生代

    新生代又分为一个Eden区和两个Survivor区。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制年老区。需要注意,两个Survivor是交替使用的,也就是说Survivor总有一个是空的。

 

3.2老年代

    大对象直接分配在老年代 ,老年代存放从新生代存活的对象。一般来说老年代存放的都是生命期较长的对象。。

 

4.方法区(持久代)

    方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,同时方法区域也是全局共享的,在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。

 

5.运行时常量池

    存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。

 

6.本地方法栈

    JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。

 

JVM内存回收策略

垃圾收集器

 

Serial:

    最基本也是历史最悠久的收集器,新生代垃圾收集器,

    单线程stop the world until garbage collecting end.

    它是client模式下默认的新生代垃圾收集器,无线程交互,简单而高效

    采用复制算法

 

ParNew:

    相当于是Serial收集器的多线程版本,其他的绝大多数特性与Serial收集器相同。

    server模式下首选的新生代收集器

    目前只有Serial和ParNew能与CMS收集器配合

 

Parallel Scavenge:

    新生代,复制算法,并行多线程收集器

    目标为达到一个可控制的吞吐量:

    吞吐量=用户代码运行时间/(用户代码运行时间+垃圾收集时间)

    主要适合在后台运算而不需要太多交互的任务

    参数: -XX:GCTimeRatio 设置吞吐率大小的参数

                -XX:MaxGCPauseMillis设置最大垃圾收集停顿时间

                -XX:UseAdaptiveSizePolicy打开gc自适应调节策略

 

Serial Old:

    老年代收集器,单线程,标记整理算法

    主要用于client模式下

    主要用途:1.在jdk1.5及之前的版本中与Parallel Scavenge搭配使用

                      2.作为CMS收集器的后备预案

 

Parallel Old:

    Parallel Scavenge的老年代版本,多线程,标记整理算法,吞吐量优先

 

CMS:

    以最短回收时间为目标,标记清除算法

    分4个过程:初始标记,并发标记,重新标记,并发清除;其中,初始标记和重新标记需 要stop the world。并发标记和并发清除耗时较长,但是可以与用户线程一起并发执行。

    缺点:并发的同时也意味着会占用cpu资源,导致吞吐率下降

               标记清除算法会导致大量的空间碎片(导致分配大对象时没有足够大的连续空间,导致提前full gc)

 

Full GC条件:

1.老年代空间不足(过多对象由新生代转入老年代,在老年代创建大对象和大数组),Full GC后仍不足,则抛出OOM异常

2.永久代存放过多class信息,系统加载的类反射的类和调用的方法较多时,不足以存放新的class或反射类或动态代理生成的类信息时

3.当老年代中的连续空间不足以存放Minor GC时,从新生代晋升到老年代的对象时。

纳兰清风

纳兰清风

粉丝 33
博文 36
码字总数 42398
作品 0
朝阳
程序员
私信 提问
加载中
请先登录后再评论。

暂无文章

Linux拜拜!微软给WSL加入GPU支持,Windows终于迎来命令行包管理工具

点击蓝字“ 大白技术控 ”关注我哟 加个“星标★”,每日良时,好文必达! 白交 发自 凹非寺 量子位 报道 | 公众号 QbitAI 看完昨晚微软Build大会,虽然开发者不能亲自到现场,但看到WSL更新...

大白技术控
05/25
0
0
GraphQL

网文、分享汇总 干货分享 | GraphQL 数据聚合层 http://www.sohu.com/a/235978606_205771 awesome-graphql https://github.com/chentsulin/awesome-graphql 一些graphql相关的java项目 周边项......

素雷
20分钟前
4
0
如何在jQuery中选择具有多个类的元素? - How can I select an element with multiple classes in jQuery?

问题: I want to select all the elements that have the two classes a and b . 我想选择具有两个类a和b所有元素。 <element class="a b"> So, only the elements that have both classe......

javail
42分钟前
15
0
MySql查询所有字段不为空值的数据及Mybatis的#号和$符的区别引起的问题

1.MySql查询所有字段不为空值的数据 搜了一上午搜不到,最后用Mybatis的foreach标签,先查询出表字段, SELECT COLUMN_NAMEFROM INFORMATION_SCHEMA.ColumnsWHERE table_name='lltest'...

不忘初心牢记使命
43分钟前
32
0
五分钟搞定WebRTC视频录制

WebRTC中文社区是一个为大家解决在使用WebRTC当中遇到问题所建立的社区,欢迎更多学习和使用WebRTC的人加入进来,一起建设。 视频录制 在之前的文章里我们提到过视频录制的两种方式:客户端录...

死磕音视频
49分钟前
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部