问个 jvm 拼接字符串, heap oom 的问题

2021-01-05 02:15:51 +08:00
 pkwenda

很简单的一段代码 1:


	public static void main(String[] args) {
		int i = 0;
		String a = "hello";
		try {
			while (true) {
				a = a + " world";
				i++;
				System.out.println(i);
			}
		} catch (Throwable e){
			System.out.println(e);  
			System.out.println(i);  
			System.out.println(a);
		}
	}

很简单的一段代码 2:

public static void main(String[] args) {
		int i = 0;
		String a = "hello";
		try {
			while (true) {
				a = a + a;
				i++;
				System.out.println(i);
			}
		} catch (Throwable e){
			System.out.println(e); 
			System.out.println(i);  
			System.out.println(a);
		}
	}

设置 1M

-Xmx1m -XX:+PrintGCDetails

反汇编结果:

结果

我不理解为什么 代码 2,我不断的加大内存,循环次数远没有达到我预期?按我的期望值,heap 空间足够 new 非常多的对象,为什么?

17
18
[GC (Allocation Failure) [PSYoungGen: 23074K->3152K(29696K)] 23074K->8280K(98304K), 0.0038643 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
19
[GC (Allocation Failure) [PSYoungGen: 24127K->544K(29696K)] 29255K->21032K(98304K), 0.0070954 secs] [Times: user=0.02 sys=0.01, real=0.00 secs] 
20
21
[Full GC (Ergonomics) [PSYoungGen: 22036K->0K(29696K)] [ParOldGen: 61448K->20931K(67584K)] 83484K->20931K(97280K), [Metaspace: 3312K->3312K(1056768K)], 0.0053285 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 20480K->0K(29696K)] [ParOldGen: 61891K->61891K(68608K)] 82371K->61891K(98304K), [Metaspace: 3312K->3312K(1056768K)], 0.0065019 secs] [Times: user=0.03 sys=0.01, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(29696K)] 61891K->61891K(98304K), 0.0007047 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(29696K)] [ParOldGen: 61891K->61873K(68608K)] 61891K->61873K(98304K), [Metaspace: 3312K->3312K(1056768K)], 0.0063003 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
java.lang.OutOfMemoryError: Java heap space
21
Heap
 PSYoungGen      total 29696K, used 761K [0x00000007bdf00000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 25600K, 2% used [0x00000007bdf00000,0x00000007bdfbe428,0x00000007bf800000)
  from space 4096K, 0% used [0x00000007bf800000,0x00000007bf800000,0x00000007bfc00000)
  to   space 4096K, 0% used [0x00000007bfc00000,0x00000007bfc00000,0x00000007c0000000)
 ParOldGen       total 68608K, used 61873K [0x00000007b9c00000, 0x00000007bdf00000, 0x00000007bdf00000)
  object space 68608K, 90% used [0x00000007b9c00000,0x00000007bd86c5c8,0x00000007bdf00000)
 Metaspace       used 3319K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 372K, capacity 388K, committed 512K, reserved 1048576K


内存瞬间被吃了很大一块

764 次点击
所在节点    Java
1 条回复
pkwenda
2021-01-05 02:24:50 +08:00
我好像看明白了,内存是呈几何倍增长的,我写的是 a + a .... 懂了,果然还得是小黄鸭 debug 法

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/741705

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX