
文章图片

文章图片

文章图片

文章图片

文章图片
Hello , 今天给各位童鞋们分享的是JVM , 赶紧拿出小本子记下来吧
一、内存溢出内存溢出的原因:程序在申请内存时 , 没有足够的空间 。
1. 栈溢出
方法
2. 堆溢出
不断创建对象 , 分配对象大于最大堆的大小(OutOfMemoryError) 。
3. 直接内存
JVM 分配的本地直接内存大小大于 JVM 的限制 , 可以通过-XX:MaxDirectMemorySize 来设置(不设置的话默认与堆内存最大值一样也会出现OOM 异常) 。
4. 方法区溢出
一个类要被垃圾收集器回收掉 , 判定条件是比较苛刻的 , 在经常动态生产大量 Class 的应用中 , CGLIb 字节码增强 , 动态语言 , 大量 JSP(JSP 第一次运行需要编译成 Java 类)基于 OSGi 的应用(同一个类 , 被不同的加载器加载也会设为不同的类) , 都可能会导致OOM 。
二、内存泄露程序在申请内存后 , 无法释放已申请的内存空间 , 导致这一部分的原因主要是代码写
1. 长生命周期的对象持有短生命周期对象的引用
例如将 ArrayList 设置为静态变量 , 然后不断地向ArrayList中添加对象 , 则 ArrayList 容器中的对象在程序结束之前将不能被释放 , 从而造成内存泄漏 。
2. 连接未关闭
如数据库连接、网络连接和 IO 连接等 , 只有连接被关闭后 , 垃圾回收器才会回收对应的对象 。
3. 变量作用域不合理
例如:
【jvm|超赞!不愧是美团内部的JVM学习手册,从头到尾全是精华】一个变量的定义的作用范围大于其使用范围 。
如果没有及时地把对象设置为 null 。
4. 内部类持有外部类
Java 的 非静态内部类 的这种创建方式 , 会隐式地持有外部类的引用 , 而且默认情况下这个引用是强引用 , 因此 , 如果内部类的生命周期长于外部类的生命周期 , 程序很容易就产生内存泄露(可以理解为:垃圾回收器会回收掉外部类的实例 , 但由于内部类持有外部类的引用 , 导致垃圾回收器不能正常工作) 。
解决办法:将非静态内部类改为 静态内部类 , 即加上 static 修饰 , 例如:
5. Hash值改变
在集合中 , 如果修改了对象中的那些参与计算哈希值的字段 , 会导致无法从集合中单独删除当前对象 , 造成内存泄露 。
使用例子来说明 。
三、内存溢出和内存泄漏辨析
- 内存溢出:实实在在的内存空间不足导致 。
- 内存泄漏:该释放的对象没有释放 , 常见于使用容器保存元素的情况下 。
- 内存溢出:检查代码以及设置足够的空间 。
- 内存泄漏:一定是代码有问题 , 往往很多情况下 , 内存溢出往往是内存泄漏造成的 。
1. 浅堆和深堆
- 浅堆(Shallow Heap):是指一个对象所消耗的内存 。
- 深堆(Retained Heap):这个对象被 GC 回收后 , 可以真实释放的内存大小 , 也就是只能通过对象被直接或间接访问到的所有对象的集合 。 通俗地说 , 就是一个对象包含(引用)的所有对象的大小 , 如图:
2. MAT的使用
内存溢出例子演示
参数说明:
-Xms5m 堆初始大小5M
-Xmx5m 堆最大大小5M
-XX:+PrintGCDetails 打印gc日志详情
-XX:+HeapDumpOnOutOfMemoryError 输出内存溢出文件
-XX:HeapDumpPath=D:/oomDump/dump.hprof 内存溢出文件保存位置 , 此文件用于MAT分析
设置参数运行后 , 内存溢出 , 程序结束 , 然后我们就可以用下载好的MAT来分析了 , 当然MAT也只是分析猜想 , 并不代表一定是这个原因导致内存溢出 。
- 一加科技|年度最佳直屏手机,一加9 RT不愧为全能“六边形战士”
- 小米科技|华为mate40不愧是一代神机,这大概是最保值的一款安卓旗舰了
- AR|薇娅几分钟卖10万台?北斗打造的AR地球仪,网友:不愧是百科全书
- 红米手机|红米Note11系列首发测评,不愧是续航彪悍\小金刚\被网友称为千元价位王者
- harmonyos|首款HarmonyOS 3新机确定,8+512G调到7688,不愧是华为!
- 铠侠|仅1899元!8GB运存+128GB+5000毫安,不愧为真香性价比
- 红米手机|从3699来到2799,红米骁龙888旗舰跳水900,不愧是亲民品牌
- vivo x|国产影像王者,8+256G卖5499,全四摄光学防抖,不愧为vivo机皇
- ssd|SSD价格杀疯了,铭瑄已低至0.5元1G,不愧是丐帮帮主
- 乌镇|前沿“黑科技”刷屏乌镇 网友:不愧是“互联网之光”
