纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

Java内存分布 再也不用怕! 让你彻底搞明白Java内存分布

香菜聊游戏   2021-06-06 我要评论
想了解再也不用怕! 让你彻底搞明白Java内存分布的相关内容吗香菜聊游戏在本文为您仔细讲解Java内存分布的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Java内存分布机制,Java内存分布下面大家一起来学习吧

一、堆内内存

堆内内存分为三大部分年轻代  老年代 和 元空间所以 堆内内存 = 年轻代 + 老年代 + 元空间下面细聊下三部分

1.1 年轻代-Young Generation

存放的是new 生成的对象

年轻代是为了尽可能快速的回收掉那些生命周期短的对象

Eden

  • 大部分对象在Eden区中生成
  • 当Eden区满时,会做一次young gc, 依然存活的对象将被复制到Survivor区, 当一个Survivor 区满时, 此区的存活对象将被复制到另外一个Survivor区

Survivor(通常2个)

  • 当两个 Survivor 区 都满时, 从第一个Survivor 区 被复制过来 且 依旧存活的 对象超过一定年龄的会被复制到 老年代(Tenured)
  • Survivor 的两个区是对称的, 没有先后关系, 所有同一个区中可能同时存在从Eden复制过来的对象 和 从前一个 Survivor 复制过来的对象
  • 把age大于-XX:MaxTenuringThreshold的对象晋升到老年代(对象每在Survivor区熬过一次其age就增加一岁)

1.2 老年代 (Old Generation)

存放了在年轻代中经历了N次垃圾回收后仍存活的对象, 是一些生命周期较长的对象.

存放那些创建的时候占用空间比较大的对象这些对象不经历eden,直接进入老年代大对象(大小大于-XX:PretenureSizeThreshold的对象)

1.3 元数据(Meta space)

存放类的数据

存放静态文件, 如静态类和方法等持久代对垃圾回收没有显著影响, 但是有些应用可能动态生成或者调用一些class, 比如Hibernate, Mybatis 等, 此时需要设置一个较大的持久代空间来存放这些运行过程中新增的类

设置持久代大小参数: -XX:MetaspaceSize, -XX:MaxMetaspaceSize

1.4 总结

图片

1、默认参数:

老年代占整个堆内存的2/3

年轻代占整个内存的1/3

Eden 区域占 整个年轻代的80%From 和 To 两个生存者区域各占10%

2、新老年代相关jvm参数

-XX:NewRatio 设置新老年代比例如-XX:NewRatio=5 代表 新老年代比例为1:5新生代占用堆内存的1/6老年代占用5/6

-XX:SurvivorRatio 设置新生代中eden和两个2个Survivo区域大小的比例如-XX:SurvivorRatio=8则eden:s1:s2=8:1:1,默认比例就是为8:1:1.

3、young GC发生在新生代中FUll GC 发生在整个堆空间中一般是老年代空间不够用就会出发FULL GC

二、堆外内存

我们的游戏服务器使用的是netty所以单说下netty,Netty的ByteBuffer采用DIRECT BUFFERS使用堆外直接内存进行Socket读写不需要进行字节缓冲区的二次拷贝,堆外内存的零拷贝.提升了效率因为操作系统内核直接把数据写到堆外内存里不需要像普通API一样操作系统内核缓存一份程序读的时候再复制一份到程序空间

2.1 java中在堆外开辟内存的方法有两种

1.用DirectBufferByteBuffer.allocateDirect(size)

2.用JNI写java的c/c++扩展在扩展里不牵扯jvm自己向系统搞内存出来

2.2 使用堆外内存的优点

1.减少了垃圾回收因为垃圾回收会暂停其他的工作

2.加快了复制的速度堆内在flush到远程时会先复制到直接内存(非堆内存)然后在发送而堆外内存相当于省略掉了这个工作

2.3堆外内存的缺点

内存难以控制使用了堆外内存就间接失去了JVM管理内存的可行性改由自己来管理当发生内存溢出时排查起来非常困难

三、垃圾回收

3.1 垃圾回收(GC)

Minor GC

  • 一般当新对象生成并且在Eden申请空间失败时就会触发MinorGC, 对Eden区域进行GC, 清除非存活对象, 并且把尚存活的对象移动到Survivor区, 然后整理两个Survivor区
  • 该方式的GC是对年轻代的Eden区进行不会影响到年老代
  • 由于大部分对象是从Eden区开始的,  所以Eden区的GC会很频繁

Major GC / Full GC

  • 老年代(Tenured) 被写满
  • 持久代(Permanent) 被写满
  • System.gc() 被显示调用
  • 上一次GC之后Heap 的各域分配策略动态变化
  • 对整个堆进行整理
  • 所消耗的时间较长, 所以要尽量减少 Full GC 的次数
  • 出现Full GC经常会伴随至少一次的Minor GC(不是绝对Parallel Sacvenge收集器就可以选择设置Major GC策略)

Major GC速度一般比Minor GC慢10倍以上

3.2 GC root

程序把所有的引用关系看作一张图从一个节点GC ROOT开始寻找对应的引用节点找到这个节点以后继续寻找这个节点的引用节点当所有的引用节点寻找完毕之后剩余的节点则被认为是没有被引用到的节点即无用的节点是需要释放内存的对象

java中可作为GC Root的对象有

1.虚拟机栈中引用的对象(本地变量表)

2.方法区中静态属性引用的对象

3方法区中常量引用的对象

4.本地方法栈中引用的对象(Native对象)

3.3常用垃圾回收器

垃圾收集器就是内存回收的具体实现下面介绍一下虚拟机提供的几种垃圾收集器

Serial收集器(复制算法)

新生代单线程收集器标记和清理都是单线程优点是简单高效

Serial Old收集器(标记-整理算法)

老年代单线程收集器Serial收集器的老年代版本

ParNew收集器(停止-复制算法) 

新生代收集器可以认为是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现

Parallel Scavenge收集器(停止-复制算法)

并行收集器追求高吞吐量高效利用CPU吞吐量一般为99% 吞吐量= 用户线程时间/(用户线程时间+GC线程时间)适合后台应用等对交互相应要求不高的场景

Parallel Old收集器(停止-复制算法)

Parallel Scavenge收集器的老年代版本并行收集器吞吐量优先

CMS(Concurrent Mark Sweep)收集器(标记-清理算法)

高并发、低停顿追求最短GC回收停顿时间cpu占用比较高响应时间快停顿时间短多核cpu 追求高响应时间的选择

G1(Garbage-First)

现在最新的回收器新生代和老年代通用

新生代收集器使用的收集器:Serial、PraNew、Parallel Scavenge

老年代收集器使用的收集器:Serial Old、Parallel Old、CMS

我们线上服务器使用的是G1 收集器

四、总结

上面列举了很多的内容但是需要记住的下面几点就可以了

    1、对象的迁移路径:出生在Eden然后在Survivor 区域来回迁移迁移一次一次增加一次年龄年龄太大的直接进入老年代

   2、 Eden区域满了 产生 minor Gc

    老年代满了产生 full gc 

    3、记住回收器是执行gc 的选择最新的G1回收器就好了


相关文章

猜您喜欢

  • js页面随机二维码验证 JavaScript+html实现前端页面随机二维码验证

    想了解JavaScript+html实现前端页面随机二维码验证的相关内容吗蜜桃婷婷酱在本文为您仔细讲解js页面随机二维码验证的相关知识和一些Code实例欢迎阅读和指正我们先划重点:js页面随机验证,js页面验证,js页面二维码下面大家一起来学习吧..
  • Java连连看算法 Java实现连连看算法

    想了解Java实现连连看算法的相关内容吗趋向_quxiang在本文为您仔细讲解Java连连看算法的相关知识和一些Code实例欢迎阅读和指正我们先划重点:java,连连看下面大家一起来学习吧..

网友评论

Copyright 2020 www.fresh-weather.com 【世纪下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式