JVM的内存的自己理解

在这里插入图片描述
jvm的内存基本就是这五个分区, 不同版本中方法区是有变动的。

堆(Heap)

java 中最大的一块内存空间, 内部会进行分代。

新生代和老年代。

新生代和老年代的大小比例建议为1:2。 如果比例不对会出现问题,我就遇到过xmx=512M xmn=384M的配置的情况。 运行一段时间后,jvm进程自动结束了。 查看GC日志发现频繁的由于内存分配失败的GC. 最后一次GC达到了72秒后程序挂了。

xmx=512M xmn=384M 这样的配置会是新生代384M 老年代只有128M. 新生代相对偏大。 这样新生代的中对象就会延迟GC, 但是每次GC的时候要复制的对象太多了,反而加大了复制时间。
另外一个问题,随着对象的存活,慢慢转到老年代中, 老年代会很快占满,当一次Minor GC后需要移动大量存活对象到老年代中, 但是此时老年代快要占满了,这个时候就会OOM. 程序无法运行下去。

新生代的垃圾回收使用的是复制清除的方式, 而老年代使用的是标记整理方式。 但是最新的G1和ZGC垃圾收集器对于垃圾收集的方式都有很大的变化, 并且最新的jdk15中ZGC收集器已经成为正式版了。

程序计数器

一小块线程独享的空间, 记录当前线程执行的自己吗的计数。 使用这个可以实现分支跳转,循环跳转, 异常跳转,线程上下文切换后的回复等。

方法区

用来存放已经被虚拟机加载的类的相关信息, 运行时常量池, 字符串常量池等等。 我们java中经常说的类加载机制中加载的类信息就是存在这里。 由于类被加载进去了后就是不可变的,所以方法区的信息是被所有的线程共享的,方法区内部存储的都是一些不可变的信息。

但是java8中已经把方法区拆了, 把运行时常量池和静态变量放入了堆中,把类的信息等其余部分放入了堆外空间中, 这个堆外空间称为元数据空间。

为何拆分迁移方法区:

  1. 方法区容易出现内存泄漏, 并且方法区的内存回收只能通过Full GC, 效率不高。
  2. java的类支持动态加载, 因此方法区的大小不易固定,放在堆外空间就可以直接扩张使用物理内存,不用受永久代大小的限制
  3. 有些虚拟机的实现中没有永久代的概念

虚拟机栈

线程私有的空间, 方法的调用就是栈帧的入栈, 返回就是调用的出栈, 栈的先进后出的特点很好的支持了方法的调用。

本地方法栈

jdk中包含很多的native的方法的调用,这些方法的调用也会伴随栈的使用, 这个栈是单独的。

java程序运行过程

启动申请内存

java程序启动了后,第一步就是根据配置(或者默认配置)向操作系统申请内存。 并根据配置把内存分配成堆栈, 方法区等

加载class

根据类加载机制,区加载class文件,初始化类生成类对象,常量等,并将这些信息放入方法区。
当然类信息并不是一次全部加载到内存中的,而是根据需要加载的。

执行main方案

main方法是一个静态方法, 任何程序都是由main方法最先启动的, 在根据main方法中的逻辑逐步生成对象,调用方法等。 在这个过程中伴随着堆的扩张, GC的回收等。

思考

java的最重要的几大特性:

跨平台

jvm很好的屏蔽了底层的差异性,使得java编译的class文件在各个平台的虚拟机上运行都能得到一致的运行结果。 为了跨平台java定义了自己的JMM模型和先行发生原则。

Mac电脑的系统中, 文件名默认是不区分大小写的,但是一些linux中文件名是区分大小写的,我就碰到过在Mac中没有问题的代码在服务器上就会报找不到文件错误。

垃圾回收

垃圾回收极大的解放了程序员的负担, 使得java程序员不用过多的关注对象内存的回收,只要写出能运行的程序,一般都不会有什么内存问题。
但是GC也不是万能的,它会掩盖很多的内存问题,使得很多的代码缺陷不容易显露出来, 直到线上爆雷了才发现。

严谨的语言格式规范

java是一个规范严格而有严谨的语言, 为了兼容以前的版本, 语言的变化有慢,而这又常常遭到别人的诟病。 但是严谨的语言可以保证程序不容易出错, 并且不同人写出的程序也大同小异, 也容易构建大型的系统而不出错。 这既是缺点也是优点吧。

最新的java版本已经是6个月发布一次, jdk15已经发布,并且很多的新的语言特性已经支持, 比如文本块, switch语句等等, java会越变越好的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值