推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > 小明java学习笔记 > JVM学习笔记(1)- jvm 内存分布

JVM学习笔记(1)- jvm 内存分布

小明java学习笔记 2018-04-16

这一篇笔记主要是记录一下java虚拟机的模型结构及内存分布。对于大多数的初级开发人员来说,他们很少会去关注JVM它是怎么去划分,也不去了解java中实例,类信息和局部变量等信息到底是存储在什么地方,那么一旦出现在性能问题就不知道怎么就做性能方面的优化了。如果是出现内存泄漏或者溢出,对于问题的排查也会一件不容易的事,无从入手。

内存分布

以上图片是我在网上盗的图,这个JVM运行时数据区域图网上太多的,懒得去重新去画。

由上图我们可以看出,JVM启动后,会将已经编译好的 class 文件加载到运行时数据区域中,也就是我们所说的内存中。运行时数据区域包括以下几个:

方法区:线程共享内存区域,用于存储加载的类信息、常量,静态变量等信息

虚拟机栈:线程私有内存区域,用于存储局部变量和参数等信息

本地方法栈:存储Native方法的数据

堆:

方法区

方法区是 java 虚拟机中所有线程共享区域,在hotspot中,方法区又被称为永久区。它还有一个别名叫Non-Heap

保存的数据:主要存放常量和类的定义信息

类的类型信息:类的完整名称、父类的完整名称、类的修饰和类型的直接接口类表

常量池:常量信息

方法信息:方法修饰符、方法返回类型、方法名称、方法参数、方法字节码、操作数栈

操作数栈:JVM执行引擎的一个工作区,当方法被调用时就会创建一个新的帧栈,当方法被执行时,虚拟机就会往帧栈中的操作数栈中进行入栈和出栈操作

参数设置(数字4只是个一例子,用户可以根据实际情况去分配)

jvm初始分配的非堆内存:-XX:PermSize=4M

jvm分配的最大非堆内存:-XX:MaxPermSize=4M

异常

如果方法的内存达到饱和且GC不能回收对应的内存时,就会抛出OutOfMemoryError错误

虚拟机栈

虚拟机栈是线程私有的内存空间,它和线程同时创建,主要是保存方法的局部变量、部分结果,并参与方法的调用和返回

参数设置

-Xss:分配的栈的大小决定了函数调用的可达深度

异常

StackOverflowError: 请求的栈深度大于最大可用的栈深度

OutOfMemoryError: 如果栈可以动态扩展,而在扩展过程中没有足够的内存空间来支持栈的扩展

堆是被所有线程共享的内存区域,它主要保存的是对象实例

组成

java 堆是通过分年代去管理堆内存的,它被分为两部分,分别是新生代和老年代。新生代又被分为三部分,即eden、from survivor  和 to survivor

eden: 刚创建的的对象实例一般会存放在 eden 中,但是并不是所有的都会存放在 eden 中,对于大对象会直接存入到老年代中,例如 eden 只分配了5M,而新创建的对象大小为 6M,这种情况下,明显 eden 存放不了,所以会直接存放到老年代中

from survivor 和 to survivor:至少经历过一次 minor GC,存活下来且能被 survivor 容衲的才会被保存到 survivor 中

老年代:存在放对象年龄大于1(新生代的对象每经历一次 Minor GC,年龄就会加1,默认最大年龄是15,但是并不是对象年龄达到15才会进行入老年代)

注: Minor GC:发生新生代的 GC,当Eden区没有足够空间进行分配时就会触发,触发会比较频繁,同时回收速度也会比较快

Major GC:发生在老年代的 GC,一般情况下 Major GC 会伴随着至少一次的 Minor GC (非绝对)

Full GC:会对整个堆进行 GC

参数设置

-Xmx: 设置最大堆内存,即新生代和老年代的大小之和的最大值

-Xms: jvm 启动时的初始堆内存大小

注:一般情况下 -Xmx 和 -Xms 的值会设置为一样大,因为 jvm 在运行的过程中会尽量将堆的内存大小控制在 -Xms 所设定的值,这导致堆内存空间不足的时候,jvm 会触发起 GC,这样会导致 jvm 频繁的发起 GC 操作

-Xmn: 新生代的内存大小(也就是说老年代的内存大小等于 -Xms 的值 - -Xmn 的值)

-XX:SurvivorRatio=x(具体的值): eden 与一个 survivor 的比例,如果 x = 8,则 eden:form survivor:to survivor=8:1:1

内存分配策略

对象优先分配在 eden 中,当 eden 区没有足够的空间进行分配时虚拟机就会发起一次 Minor GC

大对象存放到老年代中

经过多次 Minor GC 存活下来的对象保存到老年代中

问题:

1.java 虚拟机中,堆、方法区、栈和本地方法区分别存放了什么?

2.-Xms 和 -Xmx 参数表示什么?一般怎么样去设置?

3.Minor GC、Major GC 和 Full GC 发在什么时候?

4.虚拟机栈的帧栈中的局部变量表存放了什么数据?

5.内存泄漏和内存溢出有什么区别?什么时候会发生内存泄漏?

6.java 中对象是如何存储的?

虚拟机日志查看参数:-XX:+PrintGCDetails



版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《JVM学习笔记(1)- jvm 内存分布》的版权归原作者「小明java学习笔记」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注小明java学习笔记微信公众号

小明java学习笔记微信公众号:gh_2db85850978f

小明java学习笔记

手机扫描上方二维码即可关注小明java学习笔记微信公众号

小明java学习笔记最新文章

精品公众号随机推荐