一文搞懂jvm内存结构
2020-02-19 16:01 学学技术 阅读(889) 评论(0) 编辑 收藏 举报一、jvm是干什么的?
大家都知道java是跨平台语言,一次编译可以在不同操作系统上运行,怎么做到的呢,看下图:
javac把写的源代码(java文件),编译成字节码(class文件),字节码部署到linux/windows/..上,被对应的jvm解释成机器码运行,jvm的工作就是这个。
大家都知道,java不需要开发者写代码来申请、释放和管理内存,jvm在运行时帮助我们做了这个事情,即便如此,我们还是需要了解jvm的内存结构,以便排查各种和内存有关的问题,比如oom,性能调优。
二、jvm内存结构是怎样的?
Java的兄弟,有没有曾经碰到过这些问题,出现OOM是什么原因?性能慢打dump发现是在等待内存分配,怎么查?了解jvm内存结构,当出现内存相关问题时,便于分析解决问题。
下图比较清晰的展示了jvm内存结构:
1、jvm内存结构分3大块:堆内存Heap、方法区Method Area和栈Stack堆;
2、堆内存Heap:分为年轻代Young Generation和老年代Old Generation;
3、年轻代YG:又分为3部分,Eden Space、From Survivor Space、To Survivor Space.
再来看看主要的几个参数:
▪ -Xms设置堆的最小空间大小;
▪ -Xmx设置堆的最大空间大小;
▪ -XX:NewSize设置新生代最小空间大小;
▪ -XX:MaxNewSize设置新生代最大空间大小;
▪ -XX:PermSize设置永久代最小空间大小;
▪ -XX:MaxPermSize设置永久代最大空间大小;
▪ -Xss设置每个线程的堆栈大小。
三、各内存空间分别存放一些什么东西,我们写的代码对应了哪些内存空间?
1、堆内存Heap,存的是对象,所有的对象在实例化后的整个运行周期内,都被存放在堆内存中
2、方法区Method Area,存的是已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
3、栈Stack,存的是基本数据类型和堆中对象的引用
堆内存,又分年轻代和老年代,那么,什么情况下用年轻代,什么情况下会进入老年代呢?
1、运行时,新创建的对象分配在年轻代的Eden,随着时间推移,Eden会满,这时候就会触发MinorGC.
2、有几种情况,会触发对象进入老年代:
1)JVM会给对象增加一个年龄(age)的计数器,对象每“熬过”一次GC,年龄就+1,当年龄达到设置的阈值(默认为15)就会被移到老年代。(可通过-XX:MaxTenuringThreshold
调整阈值, 一次Minor GC
后,对象年龄就会+1,达到阈值的对象就移动到老年代,其他存活下来的对象会继续保留在新生代中)
2)不用等待15次GC之后进入老年代,大致是,如果一批对象的总大小大于这块Survivor(From/To)内存的50%,那么大于这批对象年龄的对象就进入老年代
3)如果设置了参数-XX:PretenureSizeThreshold
,那么如果创建的对象大于这个参数值,就直接把这个对象放入老年代,不经过新生代。这么做就可以避免大对象在新生代,屡次躲过GC,还得把他们来回复制,最后才进入老年代,浪费时间。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程