11.堆:调优,在jvm中
-
Heap一个JVM只有一个堆内存,存在垃圾。堆内存的大小可以调节。
-
类加载器读取类文件后,会把:类、方法、常量、变量保存所有引用类型的真实对象,引用废弃后真实对象在堆中成为垃圾
-
堆内存细分为3个区域:
-
新生区:
-
养老区:
-
GC垃圾回收主要存在于新生区和养老区
-
堆内存满了,OOM,程序严重out of memoryERROR
-
JDK8以后,永久存储区更新为元空间
12.新生区
-
类:产生、成长甚至死亡;大部分被在此GC掉
-
伊甸园区:所有的对象都是在此区new出来的,此区满了就会触发一次轻GC ,把幸存的移到幸存区,
-
幸存区(0、1):经过几轮轻GC,幸存区也满了那会移动到养老区
-
实际上99%的对象是临时对象。用过一次后就不在管理了,进养老去的情况不过,在幸存1区就GC了,少见oom的错误
13.老年区
- 从新生区活下来的存入到老年区,老年区满了就进行重GC。
14.永久区:和对象关系不大,无垃圾回收
14.1概述
-
此区域常驻内存,用来存放jdk自带的Class对象。包括接口数据和元数据,存储的是java运行时环境或,同jre,放在磁盘中,第三方JAR包,关闭虚拟机释放永久区
-
jdk1.6 之前:永久代,常量池在方法区中,是方法区的实现,此时永久代还在堆内。
-
jdk1.7 :永久代,慢慢退化,去永久代,常量池在堆中,常量池不好控制,方法区小,所以会经常出现永久带溢出问题。
-
1.8之前方法区逻辑上是在堆中,实际和堆内其他区完全隔离开
-
jdk1.8:无永久代,常量池在元空间中,在本地内存中,取代jvm中的方法区。运行时常量池在元空间。放常量、方法原信息、类原信息。元空间和堆不是连续物理内存,改为使用本地内存
-
oom和永久区无关,除非一个启动类加载了大量的第三方JAR包。如Tomcat部署了太多的应用,大量动态生成的反射类。不断的被加载直到内存满,就会oom
14.2 方法区是个规范:实现方式是永久代、元空间
15.堆内存调优
15.1 查看堆内存,调优命令
//返回jvm初始化的内存
long totalMemory = Runtime.getRuntime().totalMemory();
//返回虚拟机视图使用的最大内存
long maxMemory = Runtime.getRuntime().maxMemory(); //字节
//初始、最大
//-Xms500m -Xmx1024m -XX:+PrintGCDetails
/*
* 字节 byte:8个二进制位为一个字节(B),最常用的单位,字节也就是B。
1KB (Kilobyte 千字节)=1024B
1MB (Megabyte 兆字节 简称“兆”)=1024KB
1GB (Gigabyte 吉字节 又称“千兆”)=1024MB*/
System.out.println("maxMemory="+maxMemory+"字节"+maxMemory / (double) 1024 / 1024+"MB");
System.out.println("totalMemory="+totalMemory+"字节"+totalMemory / (double) 1024 / 1024+"MB");
//有损失,解释空间会丢、厂家以1000算,实际是1024
//占真实内存的1/4
/*maxMemory=3779067904字节3604.0MB
//占真实内存的1/64 = PSYoungGen+ParOldGen
totalMemory=255328256字节243.5MB*/
//oom
//1.尝试扩大堆内存看结果
//2.分析内存,看一下那个地方出现问题(专业工具)
//3.查看代码是否有死循环
/*
* Heap
PSYoungGen total 75776K, used 7815K [0x000000076b900000, 0x0000000770d80000, 0x00000007c0000000)
eden space 65024K, 12% used [0x000000076b900000,0x000000076c0a1d80,0x000000076f880000)
from space 10752K, 0% used [0x0000000770300000,0x0000000770300000,0x0000000770d80000)
to space 10752K, 0% used [0x000000076f880000,0x000000076f880000,0x0000000770300000)
ParOldGen total 173568K, used 0K [0x00000006c2a00000, 0x00000006cd380000, 0x000000076b900000)
object space 173568K, 0% used [0x00000006c2a00000,0x00000006c2a00000,0x00000006cd380000)
Metaspace used 3258K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 354K, capacity 388K, committed 512K, reserved 1048576K*/
15.2 调优命令参数列表
- 大对象直接进入老年代:指字符串和数组,虚拟机提供了一个-XX:PretenureSizeThreshold参数,大于这个值的参数直接在老年代分配这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存复制(新生代采用复制算法)
15.3 排错
-
能够看到代码第一行出错:内存快照分析工具。(eclipse中MAT)IDEA(Jprofiler工具)
-
Debug一行行分析代码
-
MAT/Jprofiler测试工具
-
分析Dump内存文件,快速定位内存泄露
-
获得堆中数据
-
获得大的对象
-
…
15.4 jprofiler安装
/*-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError*/ vm option
下一篇:jvm探究-02-jvm脉络梳理3-GC垃圾回收
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123971.html