先看一个内存溢出
1 | List<Demo> demoList = new ArrayList<Demo>(); |
- 上述代码会不断创建Demo对象,直到内存溢出报错
1
2
3
4
5
6
7
8Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
at java.util.Arrays.copyOf(Arrays.java:3181)
at java.util.ArrayList.grow(ArrayList.java:265)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
at java.util.ArrayList.add(ArrayList.java:462)
at cn.xwmdream.Main.main(Main.java:11)
分析内存溢出
- 在虚拟机参数中添加-XX:+HeapDumpOnOutOfMemoryError可以查看虚拟机内存溢出的错误
- 同时增加 -Xms20m -Xmx20m可以限制堆大小最大最小都是20m,可以更快复现堆内存溢出错误
此时在根目录就会产生一个.hprof文件记录了此次内存溢出错误的快照
- 打开mat(Memory Analyzer Tool)内存分析工具,在file中加载刚刚生成的hprof文件
图片错误 - 通过摘要信息发现Problem Suspect1表示可能出现问题的区域,占了16m(一共内存限制是20m)
- 点击上面图标从左数第三个打开dominator_tree查看堆内存树信息
图片错误 - shallow Heap表示对象本身占用的内存大小(不包括引用对象),Retained Heap表示当前对象大小加上当前可直接或者间接引用对象大小的总和
- 可以看到内存泄漏发生在main方法(占用了96%的内存),是因为Object对象,点开是因为Demo对象太多(810325个)导致了内存泄漏,此时就要去main方法分析这一段代码并解决即可,针对这个样例程序可以优化代码或者改大堆内存限制或者增大物理内存
java发展史
java技术体系
- code->编译器->class->java vm
- 对于相同的class在不同平台使用不同的javavm可是实现相同的效果
java技术体系
- Java程序设计语言
- 各硬件平台上的Java虚拟机
- class文件格式
- Java api
- 第三方Java类库
Java虚拟机产品
Sum Classic Vm
- 世界上第一款商用的虚拟机
- 1996 java1.0发布的虚拟机
- 纯解释器的方式来执行Java代码,所以运行效率比较慢
Exact VM
- sun公司对上面虚拟机的优化
- Exact Memory Management准确时内存管理
- 编译器和解释器混合工作以及两级编译器
- 只在Solaris平台发布,英雄气短
HotSpot VM
- 现在jdk用的虚拟机,称霸武林
- 引入更多代码优化的技术
KVM
- kilobyte 简单,轻量,高度可移植
- 在手机平台上运行
JRockit
- BEA公司开发
- 世界上最快的Java虚拟机
- 专注于服务端应用
- 优势:
- 垃圾收集器;
- MissionControl服务套件
该套件开销小,可以寻找生产环境中的内存泄漏
java类加载
- 再Java代码中,类型的加载、连接与初始化过程都是在程序运行期间完成的
- 提供了更大的灵活性,增加了更多的可能性