Java应用内存区域

Jvm版本不同内存格局不同,本文以java8常见的情况为例。

Java运行时内存结构主要有以下几部分:

1、方法区(元空间):大小较固定

2、堆(Heap):主要、可控

3、虚拟机栈(Stack):主要、可控

4、本地方法栈:非Java程序员代码

5、程序计数器:极小

6、直接内存:记得释放

7、其他jvm运行内存:较小,不可控

        在操作系统中使用java命令启动进程,jvm启动,把硬盘上的class文件读取到内存。(注意这里java类是懒加载,不会直接把classpath下的class完全加载到内存中,首次用到时才会加载。)

  1. 元空间:Class文件被jvm解析后类信息以特定格式存放到方法区,java8以后叫元空间。可见元空间的大小主要取决于这个应用的类数量、代码量。所以一般不必限制元空间的大小,它不会随意增大。对于不涉及代码热更新、类卸载的应用,也不必考虑它的垃圾回收。(注意元空间的垃圾回收和堆内存的垃圾回收不是同一个)元空间大小一般几十M到小几百M左右。
  2. 堆内存:主要包括运行创建的对象和数组,以及字符串常量池。java程序启动参数Xms和Xmx即是控制的堆内存大小。堆内存分为年轻代和老年代,默认以1 : 2的比例瓜分整个堆。一般情况下对象在年轻代部分创建,年轻代满了就会触发youngGC(年轻代垃圾回收),一个对象在经历一定次数youngGC后如果仍被程序使用着,则说明这个对象的生命周期比较稳定,就会转移到老年代长期存活,youngGC便管不到它了,当遇到老年代内存不足时会触发fullGG(整堆垃圾回收),此时如果不能清理出足够的空间来放新对象,就会抛出OOM: Java heap space 异常。 对于堆内存大小的控制主要是设置Xms、Xmx,和新生代老年代比例-XX:NewRatio。一般不必设置比例,如果明确应用中大部分对象的存活时间较长(譬如大量的static对象、单例对象,不是随着一个http请求而生死),可以调大老年代大小。对于Xms和Xmx,可以设置相同值,避免堆大小动态调整——以内存空间换性能,一般的应用设置1G到2G足够,不要设置太大否则fullGC时耗时太长也会发生Error并影响性能。
  3. 栈内存:主要是控制虚拟机栈的大小,参数是Xss。栈内存是线程独享的,即一个线程一个栈,Xss的大小设置一般不超过1M,这个参数设置的是每一个线程栈的大小,如果你的java应用中同时存活有1000个线程,那么栈最大占用的物理内存就是1000M。栈内存中存放的是一个个的栈帧,一个栈帧对应一个方法,每有一个方法调用就往栈中压入一个对应的栈帧,所以Xss的大小主要取决于java方法调用链的长度以及方法中局部变量的数量。栈如果发生内存溢出,异常为StackOverflowError,发生的主要原因就是方法调用链太长比如出现了递归调用。

这里说一个常见的问题:java中对象的传递是值传递还是引用传递?熟悉了堆内存和栈内存就能知道,方法调用是在栈内存中发生的,栈内存中保存的是基本类型数据的值和引用类型数据的引用,所以传入方法的参数就是复制一份这个基本类型的值,或者复制一份这个引用类型的引用。

        4. 程序计数器:每个线程一个,极小,忽略。

        5. 直接内存:nio中有api可以使用直接内存,一般用作文件传输的缓冲区,提高性能,如果使用了记得释放即可。

附:OOM的问题排查,在java应用启动时可以添加参数-XX:+HeapDumpOnOutOfMemoryError和-XX:HeapDumpPath=<path>来设置当应用出现OOM时自动生成内存快照,也可以在运行时使用jmap -dump:format=b,file=<dump_file_path> <pid>命令来生成当前内存快照dump文件,使用工具 VisualVM或MAT分析dump文件可以看出在当时各类型对象的数量和大小,找到大对象等,从而推测出内存泄露的位置。

  • 15
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坏猫警长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值