[Java Jvm]-Java运行时内存区域学习总结

[Java Jvm]-Java运行时内存区域学习总结

学习博客:
java虚拟机内存区域的划分以及作用详解:https://www.cnblogs.com/whgk/p/6138522.html
JVM的内存区域划分 : https://www.cnblogs.com/dolphin0520/p/3613043.html

一.Java虚拟机运行主要流程:

Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行。
在这里插入图片描述

二.Jvm运行时数据区概要:

虚拟机栈即Java栈
在这里插入图片描述
重点:
1.引用类型总是被分配到“堆”上。不论是成员变量还是局部
2.基础类型总是分配到它声明的地方:成员变量在堆内存里,局部变量在栈内存里。
3.静态变量存在于方法区即静态区(方法区包含整个程序中唯一存在的元素)
4:Java中的常量池(字符串常量池、class常量池和运行时常量池) :https://blog.csdn.net/zm13007310400/article/details/77534349
5. 理解Java字符串常量池与intern()方法:https://www.cnblogs.com/justcooooode/p/7603381.html

三. 虚拟机栈结构概要:

在这里插入图片描述

  1. 运行程序,CarTest.java由编译器编译就会变为CarTest.class,将CarTest.class加入方法区,检查字节码是否有常量,若有(DEFAULT_COLOR)加入运行时常量池;
  2. 遇到main方法,创建一个栈帧,入虚拟机栈,然后开始运行main方法中的程序
  3. Car c1 = new Car(); 第一次遇到Car这个类,所以将Car.java编译为Car.class文件,然后加入方法区,跟第一步一样。然后new Car()。就在堆中创建一块区域,用于存放创建出来的实例对象,地址为0X0010.其中有两个属性值 color和num。默认值是null 和 00
  4. 然后通过c1这个引用变量去设置color和num的值,
  5. 调用run方法,然后会创建一个栈帧,用来装run方法中的局部变量的,入虚拟机栈,run方法结束之后,该栈帧出虚拟机栈。又只剩下main方法这个栈帧了
  6. 接着又创建了一个Car对象,所以又在堆中开辟了一块内存,之后就是跟之前的步骤一样了。

四. Java 堆概要

4.1 引用类型

1 、强引用 GC不会回收
只要程序通过 new 关键字创建了对象,那么垃圾回收期永远不会进行对对象的回收,除非是系统内存不够,即便如此,JVM也就只是抛出OutOfMemory()异常,当然如果对象的引用被释放后。这个对象将会被释放掉。那么如何清空这个对象的引用呢?对象的引用是存放在JVM的栈内存中,所以我们清空栈里面的引用自然就清除了这个对象所占用的内存空间。
2 、软引用 资源不够时GC会回收
使用场景:当用户需要实现类似缓存的功能,在内存足够的情况下直接通过软引用取值,无需从繁忙的真实来源查询数据,提升速度;当内存不足时,自动删除部分缓存数据,从真正的来源查询相关数据。
3 、弱引用 第一次标记 第二次GC不管资源是否充足也回收
弱引用主要用于监控对象是否已经被垃圾回收器标记为即将回收的垃圾,可以通过弱引用的isEnqueued方法返回对象是否被垃圾回收器标记。
4、虚引用(幽灵引用)
虚引用主要用于检测对象是否已经从内存删除。虚引用是话语权级别最低的引用了,只要垃圾回收开始工作,那么虚引用就会被回收》

4.2 GC

一.引用计数法
Android智能指针
二.标记清除法
三.根搜索法
可以作为GCRoot的对象有:
虚拟机栈(栈帧中的本地变量表)中引用的对象。
方法区中类静态属性引用的对象。
方法区中常量引用的对象。
本地方法站中JNI引用的对象。
四.分代
整个Java堆可以切割成为三个部分:
1.Young(年轻代):

  • Eden(伊利园):存放新生对象。
  • Survivor(幸存者):存放经过垃圾回收没有被清除的对象。

2.Tenured(老年代):对象多次回收没有被清除,则移到该区块。
3.Perm:存放加载的类别还有方法对象。

4.3 如何避免OOM发生

[Android]Context泄露之谜:Handle & 内部类: https://www.jianshu.com/p/63aead89f3b9
Java gc(垃圾回收机制)小结,以及Android优化建议:https://www.jianshu.com/p/214e42fc0d37
Android内存泄露——全解析和处理办法:https://www.cnblogs.com/qlky/p/7325139.html
如何避免OOM总结:https://www.jianshu.com/p/6cbd5bc49464

  1. 尽早释放无用对象的引用,如果程序允许,尽早将不用的引用对象赋为null,这样可以加速GC的工作;
  2. 尽量少用finalize函数,它会加大GC的工作量,因此尽量少采用finalize方式回收资源;
  3. 注意集合数据类型,包括数组,树,图,链表等数据结构,这些数据结构对GC来说,回收更为复杂,所以使用结束应立即置为null,不要等堆在一起;
  4. 尽量使用StringBuffer,而不用String来累加字符串;
  5. 能用基本类型如int,long,就不用Integer,Long对象。基本类型变量占用的内存资源比相应对象占用的少得多;
  6. 尽量少用静态对象变量,静态变量属于全局变量,不会被GC回收,它们会一直占用内存;
  7. 合理使用 软引用 和 弱引用
  8. 避免在Activity中使用非静态内部类,会持有外部类activity的引用,导致无法释放activity,如AsyncTask,Handler,TimerTask等。可以使用静态内部类或者使用软引用指向。
  9. 使用更加轻量的数据结构,考虑使用ArrayMap/SpareseArray而不是传统的HashMap等数据结构,Android系统为移动系统设计的容器ArrayMap更加高效,占用内存更少,因为HashMap需要一个额外的实例对象来记录Mapping的操作。而SparesArray高效的避免了key和value的自动装箱,而且避免了装箱后的解箱。
  10. 减少Bitmap对象的内存占用 ,
  • nSampleSize:缩放比例,在把图片载入内存之前,我们需要计算一个合适的缩放比例,避免不必要的大图载入。
  • decode format:解码格式,选择ARGB_8888/RBG_565/ARGB_4444/ALPHA_8,存在很大差异。
  1. 使用OnTrimMemory优化: https://www.jianshu.com/p/5b30bae0eb49
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值