Java内存相关知识

Java内存问题排查和解决

内存都有啥

  • 编译后地址是逻辑地址,需要经过编译映射到物理内存

  • MMU负责地址的转换

  • 可用内存 = 物理内存 + 虚拟内存(swap)

  • RES 实际内存占用

  • 可用内存 = free + buffers + cached

  • linux使用时,迅速占满内存

  • 堆:JVM堆中的数据是共享的,是占用内存最大的一块区域

  • 虚拟机栈:Java虚拟机栈,是基于线程的,用来服务字节码指令的运行

  • 程序计数器:当前线程所执行的字节码的行号指示器

  • 元空间:方法区的位置,非堆

  • 本地内存:其他的内存占用空间

Java内存管理基本概念:

内存:

  • Java内存
  • 操作系统

Java内存:

  • Java堆内存
  • 元空间(堆外)

Java堆内存

  • JVM分配的Java内存对象
  • 通常使用 -Xmx -Xms 控制大小

元空间

  • Metaspace默认无上限
  • 原方法区在这里

内存划分:

  • JVM进程内存 = 堆内内存 + 堆外内存
  • 堆外内存 = 元空间 + CodeCache + 本地内存
  • 堆外内存和操作系统剩余内存是此消彼长的关系
  • 可分配的内存大小 = 物理内存 - SWAP

32位内存限制4GB,目前ZGC支持16TB内存

控制参数:

  • 堆 -Xms -XMx
  • 元空间 -XX:MaxMetaspaceSize -XX:MetaspaceSize
  • 栈: -Xss
  • 直接内存: -XX:MaxDirectMemorySize
  • 其他堆外内存无法控制

垃圾回收:

  • 自动垃圾回收:JVM自动检测和释放不再使用的内存
  • Java运行时JVM会有线程执行GC,不需要程序员显示释放对象
  • GC发生的时机由复杂的策略判断,自动触发,不受外部控制
  • 不同的垃圾回收算法,甚至不同的JVM版本,回收策略都不一样

内存问题两种形式:

  • 内存溢出(OutOfMemoryError)OOM:
    • 堆是最常见的情况
    • 堆外内存排查困难
  • 内存泄漏(MemoryLeak)ML:
    • 分配的内存没有得到释放
    • 内存一直在增长,有OOM风险
    • GC回收时回收不掉
    • 能够回收但很快又占满

内存问题影响:

  • 发生OOM Error,应用停止
  • 频繁GC,GC时间长,GC线程时间片占用高
  • 服务卡顿,请求响应时间边长

排查困难:

  • 问题时间跨度大
  • 问题解决耗费精力
  • 现场保护意识不足

简单问题场景:

  • 物理内存不足
    • 主机物理内存非常少
    • 主机上应用进程非常多
  • 给应用JVM分配的内存小
  • 错误的引用方法,发生了内存泄漏,没有及时切断与GC roots的关系
  • 并发量大,计算需要内存大
  • 没有控制取数范围
  • 加载了非常多的Jar包
  • 对堆外内存无限制的使用

垃圾回收器:

  • CMS:将在Java14正式移除
  • G1:主流应用的垃圾回收器
  • ZGC 大容量(16TB),低延迟(10ms)的垃圾回收器

可达性分析法:

  • Reference Chain
  • 可达性分析法
  • GC过程:找到活跃的对象,然后清理其他的

引用级别:

  • 强引用:属于最普通最强硬的一种存在,只有在和GC Roots断绝关系时,才会被消灭掉
  • 软引用:只有在内存不足时,系统则会回收软引用独享
  • 弱引用:当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象
  • 虚引用:虚引用主要用来跟踪对象被垃圾回收的活动

对象何时提升(Promotion)

  • 常规提升 对象够老
  • 分配担保 Survivor空间不够,老年代担保
  • 大对象直接在老年代分配
  • 动态对象年龄判定

瞬时态和历史态

  • 瞬时态:
    • 指当时发生的快照类型的元素
    • 体积大
  • 历史态
    • 指按照频率抓取的
    • 有固定监控项的资源变动

预防措施:

  • 减少创建大对象的频率:比如byte数组的传递
  • 不要缓存太多的堆内存数据:使用guava的weak引用模式
  • 查询的范围一定要可控:如分库分表中间件;ES等有同样问题
  • 用完的资源一定要close掉:可以使用新的try-with-resources语法
  • 少用intern:字符串太长,且无法复用,就会造成内存泄漏
  • 合理的Session超时时间
  • 少用第三方本地代码,使用Java方案替代
  • 合理的池大小
  • XML(SAX/DOM)、JSON解析时要注意对象大小

总结:

  • 问题发现:
    1. 确保加入了日志和自动转储参数
    2. 确定物理内存足够:free
    3. 确定Java进程内存足够:jmap
    4. 确定主机环境,剩余内存大小
    5. 查看Glog和其他日志
    6. 使用jstack对线程进行摸底
    7. 对堆外内存进行排查
    8. 保留现场
  • 采取措施
  • 重复观察
  • 问题解决
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354