我的编程空间,编程开发者的网络收藏夹
学习永远不晚

java内存分布的实现方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

java内存分布的实现方法

本篇内容主要讲解“java内存分布的实现方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java内存分布的实现方法”吧!

目录
  • 一、堆内内存

    • 1 年轻代-Young Generation

    • 2 老年代 (Old Generation)

    • 3 元数据(Meta space)

    • 4 小结

  • 二、堆外内存

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

    • 2 使用堆外内存的优点

    • 3堆外内存的缺点

  • 三、垃圾回收

    • 1 垃圾回收(GC)

    • 2 GC root

    • 3常用垃圾回收器

一、堆内内存

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

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 小结

java内存分布的实现方法

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中在堆外开辟内存的方法有两种

用DirectBufferByteBuffer.allocateDirect(size)

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

2.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的对象有

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

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

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

本地方法栈中引用的对象(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)

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

新生代收集器使用的收集器:SerialPraNewParallel Scavenge

老年代收集器使用的收集器:Serial OldParallel OldCMS

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

四、总结

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

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

Eden区域满了 产生 minor Gc

老年代满了产生 full gc

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

到此,相信大家对“java内存分布的实现方法”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

java内存分布的实现方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java内存分布的实现方法

本篇内容主要讲解“java内存分布的实现方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java内存分布的实现方法”吧!目录一、堆内内存1.1 年轻代-Young Generation1.2
2023-06-20

Java中的内存分布有哪些

今天就跟大家聊聊有关Java中的内存分布有哪些,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java内存分布:Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不
2023-05-31

mongo分布式锁Java实现方法(推荐)

一、分布式锁使用场景:代码部署在多台服务器上,即分布式部署。多个进程同步访问一个共享资源。二、需要的技术:数据库:mongojava:mongo操作插件类 MongoTemplate(maven引用),如下:
2023-05-31

C++内存池的实现方法

这篇文章主要讲解了“C++内存池的实现方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++内存池的实现方法”吧!目录一、内存池基础知识1、什么是内存池1.1 池化技术1.2 内存池2、内
2023-06-20

redis分布式共享内存的方法是什么

Redis分布式共享内存的方法主要有以下几种:1. Redis Cluster:Redis Cluster是Redis官方推出的分布式解决方案,它通过在多个Redis节点之间分片数据来实现分布式共享内存。每个节点都存储部分数据,并且通过主从
2023-08-23

Netty分布式ByteBuf使用subPage级别内存分配的方法

这篇文章主要介绍“Netty分布式ByteBuf使用subPage级别内存分配的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Netty分布式ByteBuf使用subPage级别内存分配的方法”
2023-06-29

zookeeper实战之实现分布式锁的方法

Zookeeper实现分布式锁比Redis简单,Zookeeper有一个特性,多个线程在Zookeeper里创建同一个节点时,只有一个线程执行成功,Zookeeper主要是利用临时有序节点这一特性实现分布式锁,感兴趣的朋友跟随小编一起学习吧
2022-11-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录