溢出区域
内存溢出分为堆内存溢出和栈内存溢出 如果虚拟机在扩展堆时无法申请到足够大的内存空间时,就会抛出outOfMemoryError 如果线程请求的栈深度大于虚拟机所允许的最大深度,则抛出StackOverflflowError栈溢出
public class TestOverFlow { public static void main(String[] args) { pop(); } public static void pop(){ pop(); } }
堆溢出
public static void main(String[] args) { List<String> list = new ArrayList<>(); while (true) { list.add("Hello"); } //pop(); }
为了更好检测和查看溢出原因在运行前先设置jvm参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/xianghan/Desktop/bak -Xmx2m -Xms2m jvm参数含义请参考:https://www.oracle.com/java/technologies/javase/vmoptions-jsp.html
生成的二进制文件格式为hprof,可以使用jprofifile打开分析具体导致异常的代码
线程数过多导致堆溢出
PS:此代码慎执行!!!! !!!在执行前一定小心保存当前工作内容,防止机器卡死public static void main(String[] args) { try { while (true){ Thread thread=new Thread(new Runnable() { @Override public void run() { while (true){ } } }); System.out.println(thread.getName()); thread.start(); } } catch (Exception e) { e.printStackTrace(); } }
常量池溢出
// -Xmx10m -Xms10m public static void main(String[] args) { List<String> list = new ArrayList<>(); int i = 0; while (true) { list.add(String.valueOf(i++).intern()); } }String.intern()是一个Native方法,它的作用是:如果字符串常池中已包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象,否则将此String对象包含的字符串添加到常池中,并且返回此string对象的引用。在JDK1.6及之前的版本中,由于常池分配在永久代内,我们可以通过-XX:PermSize=10M -XX:MaxPermSize=10M。MaxPermSize限制方法区大小从而间接限制其中常量池的容量。
本机直接内存溢出
如果不指定MaxDirectMemorySize那么直接内存与堆内存一样大 PS:运行此代码风险较大直接死机public static int _1MB=1024*1024; //-Xmx20M -XX:MaxDirectMemorySize=10M public static void main(String[] args) throws Exception{ Field unsafeField= Unsafe.class.getDeclaredFields()[0]; unsafeField.setAccessible(true); Unsafe unsafe =(Unsafe) unsafeField.get(null); while (true){ unsafe.allocateMemory(_1MB); } }
标签:分析,String,void,static,内存,public,溢出 From: https://www.cnblogs.com/xinay/p/16622656.html