一、jvm运行机制
-
写一个程序,让程序在运行之后,最终抛出由于Perm区溢出引起的OOM,给出运行的jdk版本,程序源码,运行参数,以及系统溢出后的截图、程序所依赖的jar包说明,并说明你的基本思路
``` package com.tencent.tubemq.example; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * description: 在jdk1.8中,其实已经没有永久代这一说了,取而代之的是一个叫元空间(Meta space)。而常量池放到了堆中,所以也就不会出现PermGen space了 那么如果想看到metaspace的异常怎么做呢? 一个是可以把这两个值设置的足够小,那么启动就会报错了。 -XX:MetaspaceSize=3M -XX:MaxMetaspaceSize=3M 一个是可以使用jdk动态加载技术,例如cglib动态的生成大量的数据来达到 * * @author: dawn.he QQ: 905845006 * @email: dawn.he@cloudwise.com * @email: 905845006@qq.com * @date: 2019/9/22 8:44 AM */ public class PermOOM { public static void main(String[] args) { List<String> list = new ArrayList<String>(); while (true) { list.add(UUID.randomUUID().toString().intern()); System.out.println(UUID.randomUUID().toString().intern()); } } } ```
系统溢出后打印的异常栈: Error occurred during initialization of VM MaxMetaspaceSize is too small.
-
你能想到有什么办法,可以让一个程序的函数调用层次变的更深。比如,你在一个递归调用中,发生了stack的溢出,你可以做哪些方面的尝试,使系统尽量不溢出?阐述你的观点和原因。
答:首先了解到线程在调用每个方法的时候,都会创建相应的栈,在退出方法的时候移出栈桢,并且栈是私用的,也需要占用空间,所以让一个程序的函数调用层次变的更深 减少栈贞的空间很必要。或者增大线程的线的大小。 ``` package com.tencent.tubemq.example; /** * jdk8 启动参数是默认参数 * * @author dawn.he */ public class OverflowTest { private volatile int i = 0; public static void main(String[] args) { OverflowTest o = new OverflowTest(); try { // 没增加方法栈占用空间前 over flow deep:19590 // 增加方法栈占用空间后 over flow deep:5547 String s = "1"; o.deepTest(s); } catch (Throwable e) { System.out.println("over flow deep:" + o.i); e.printStackTrace(); } } private void deepTest(String s) { //这里注释掉s 的赋值操作可以减少方法栈的占用空间 s = "一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字"; s += "一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字"; s += "一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字一段长长的汉字"; ++i; deepTest(s); } } ```
所以我想到的方法是:减少方法栈占用空间,或者增加线程栈的空间。
-
jvm启动流程
-
jvm基本结构
-
pc寄存器
-
方法区
-
java 堆
-
java 栈
-
内存模型
-
可见性
-
有序性、指令重排
-
指令重排基本原则
-
解析和编译运行