我们偶尔就会遇到OutOfMemoryError,面试的时候总是能够被问道,可明明背好的面试题临时又不会了,答出来也很生硬,自己都想让自己快点“回家等通知”,那我们就通过下面的两个例子了解一下吧。
开发环境:idea
例1,这个例子会抛出个OutOfMemoryError异常
public static void main(String[] args) {
String str = "wuxiangshangjiang";
while (true){
str += str + new Random().nextInt(88888888) + new Random().nextInt(99999999);
}
}
运行会报错(稍微卡顿,具体看电脑),内存溢出了。
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:674)
at java.lang.StringBuilder.append(StringBuilder.java:208)
at com.bingoyes.Demo01.main(Demo01.java:14)
接着再来个例子,看看这个程序默认内存到底有多大,就溢出??我这可是祖传电脑---
例2展示默认内存大小
是在例1上修改的,加了几行。
public static void main(String[] args) {
//可分配的最大内存,超过就OOM,默认物理机的1/4
long max = Runtime.getRuntime().maxMemory();
//当前分配的总内存,默认物理机的1/64
long total = Runtime.getRuntime().totalMemory();
//剩余可用内存,max - total,
long free = Runtime.getRuntime().freeMemory();
System.out.println("可分配的最大内存,超过就OOM,max=" + max + "字节\t" + (max/(double)1024/1024) + "MB");
System.out.println("当前分配的总内存,total=" + total + "字节\t" + (total/(double)1024/1024) + "MB");
System.out.println("剩余可用内存,free=" + free + "字节\t" + (free/(double)1024/1024) + "MB");
//----------
String str = "wuxiangshangjiang";
while (true){
str += str + new Random().nextInt(88888888) + new Random().nextInt(99999999);
}
}
肯定还会报错OutOfMemoryError,但是报错前会打印出我命令它给我的东西。
可分配的最大内存,超过就OOM,max=3782737920字节 3607.5MB
当前分配的总内存,total=255328256字节 243.5MB
剩余可用内存,free=248669184字节 237.1494140625MB
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:674)
at java.lang.StringBuilder.append(StringBuilder.java:208)
at com.bingoyes.Demo01.main(Demo01.java:26)
打印的很明白了。最大是3607M,大约物理机总内存的1/4。
到此我们知道了我们程序运行的时候默认的jvm空间大小,那该怎么修改呢?
通过增加Xms和Xmx命令,看看效果。看图
指定位置输入:-Xms16m -Xmx19m
应用后OK退出,这样就会运行的时候带上这个命令。
再运行输出,比我们设置的少了一点点,我学习的时候有明白过为啥,但是忘了。知道是对的就行了暂时。
可分配的最大内存,超过就OOM,max=18874368字节 18.0MB
当前分配的总内存,total=16252928字节 15.5MB
剩余可用内存,free=12321696字节 11.750885009765625MB
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:674)
at java.lang.StringBuilder.append(StringBuilder.java:208)
at com.bingoyes.Demo01.main(Demo01.java:26)
通过上面配置我们了解到了。
-Xmx:可分配的最大内存,超过就OOM
-Xms:是运行时分配的空间大小,虽然分配了,通过剩余可用内存free可以知道,并没有都用了。
最后拓展一下,增加个命令,能够直观的知道jvm中的堆Heap内部其实又分了好几个区域。
-Xms16m -Xmx19m -XX:+PrintGCDetails
输出
运行jar包时用的命令如下:
java -jar text.jar --Xms16m -Xmx19m
以上