为了账号安全,请及时绑定邮箱和手机立即绑定

JVM系统优化实践(2):JVM内存与回收

标签:
Java JVM

您好,我是湘王,这是我的慕课手记,欢迎您来,欢迎您再来~


上次把JVM的类加载过程粗略地过了一遍今天再来看看JVM运行代码时,系统里发生了什么

就像家里的柴茶要分别放在不同的缸子里一样JVM也会把运行时需要的数据放在不同的存储空间JVM的存储空间大概都有这么些家当」:方法区计数器

https://img1.sycdn.imooc.com//63f4a0820001af2c07320523.jpg

 

JDK1.8之前的版本中,称为“方法区”,代表JVM中的一块区域,主要存放从.class加载进来的类。JDK1.8之后的版本中,改为“metaspace”(元数据空间):

https://img1.sycdn.imooc.com//63f4a0880001876706330457.jpg

 

那么JVM又是怎么知道程序执行到了哪里运行了几次又是怎么被引用的呢这时候程序计数器就出场了就是用来记录当前执行的字节码指令的位置的。

https://img1.sycdn.imooc.com//63f4a08d0001c95807700535.jpg

 

由于JVM是支持多线程的,所以每个线程都会有自己的程序计数器它不是共用的话这一点容易引起误会):

https://img1.sycdn.imooc.com//63f4a093000125d209280554.jpg

 

而线程是在中运行的

1、保存每个方法内的局部变量等数据的区域,每个线程都有自己的JVM栈;

2、线程执行某个方法,就会对该方法的调用创建一个对应的栈帧;

3、栈帧里就有这个方法的局部变量表、操作数栈、链接等,可以说就是线程自己的小王国

4、任何方法的调用,都遵循“先入栈,再出栈”的方式。

https://img1.sycdn.imooc.com//63f4a0970001ab1309840372.jpg

 

https://img1.sycdn.imooc.com//63f4a0a00001663c10050565.jpg


 

不同JVM堆用来存放代码中创建的各种对象及其实例的地方JVM栈中的局部变量只是一个引用地址(即指针),指向Java堆内存里实际存储的对象实例的地址。

https://img1.sycdn.imooc.com//63f4a0a400014da406570410.jpg

 

Java运行时大致会经历这个过程

1、JVM进程启动;

2、类加载器加载;

3、将加载的信息存放在JVM不同的内存区域;

4、执行main()方法;

5、在main线程中将main()方法入栈;

6、如果需要创建实例对象,则在JVM堆中创建;

7、由栈中的局部变量引用这个堆内存实例对象的地址;

8、执行各个不同方法的时候,依次入栈再出栈。

https://img1.sycdn.imooc.com//63f4a0a900014a3810380571.jpg

 

另外,在JDK底层API中,有些已经不是Java代码写的了,如I/O、Socket、网络等。调用native方法时,也会通过类似Java虚拟机栈的栈帧完成。通过NIO中的allocateDirect这种API,可以在Java堆外分配空间,然后通过JVM里的DirectByteBuffer来引用和操作,它已经不属于JVM了。

既然有了这些家当分配了内存那么在Java堆中创建的对象实例,都是要占用内存资源的,而且内存资源是有限的所以当资源不再被使用时,JVM通过一个后台自动运行的线程进行资源回收:垃圾回收GC机制

https://img1.sycdn.imooc.com//63f4a0b3000194fa07360413.jpg


针对JVM的特点一些开发时需要注意的

1、不要在for循环里创建对象,而在循环外面声明,for循环里对一个对象修改数据即可,这样就不会造成大量的Java堆内存被占用;

2、Object Header(4字节)+ Class Pointer(4字节)+ Fields(看存放类型),但是JVM内存占用是8的倍数,所以结果要向上取整到8的倍数;

3、实例变量得在创建类的实例对象时才会初始化,类的初始化阶段,仅仅是初始化类而已,跟对象无关,用new关键字才会构造一个对象出来;

4、类的class对象不是在准备阶段创建的,准备阶段是分配内存空间的;

5、自定义类加载器就是自己写一个类,继承ClassLoader类,重写类加载的方法,然后在代码里面可以用自己的类加载器将某个路径下的类加载到内存里来;

6、类加载器不是把jar包里的所有类一次性全部加载进去,而是首先加载包含main方法的主类(这个主类在启动时必须唯一指定),接着是运行代码的时候,需要用什么类就加载什么类。


感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消