《深入理解java虚拟机》2.4之OutOfMemory异常实战

<strong>1、java堆内存溢出异常</strong>
package com.lyzx.jvm;

import java.util.ArrayList;
import java.util.List;

/**
 * 测试java堆内存溢出异常
 * 使用的参数是
 * -Xms10M  java堆内存的最小值
 * -Xmx10M  java堆内存的最大值
 * 当对内存的最小值和最大值都相同时java虚拟机就不会去动态扩展对内存的大小了
 * 出现堆内存溢出的主要原因是对象"太多",比如对程序来说没有用的对象持有的时间过长
 */
public class HeapOutOfMemory {
    private static int count = 0;

    public static void main(String[] args) {
        System.out.println("start");

        List<BigObject> container = new ArrayList<>();
        while(true){
            try{
                count++;
                System.out.println("===="+count);
                container.add(new BigObject());
            }catch (Exception e){
                System.out.println("count="+count);
                e.printStackTrace();
            }
        }
    }
}

class BigObject {
    private Long[] bigArr = new Long[10000];
}

可以看到java堆内存溢出如下

 

 

2、java栈内存溢出

 

package com.lyzx.jvm;

/**
 * 测试虚拟栈和本地方法栈内存溢出
 * 一般来说栈溢出是因为调用的方法层次太多,超过了虚拟机允许的最大限制
 * 使用的参数是
 * -Xss 这个参数控制栈的大小,注意在hotspot虚拟机上只由-Xss参数控制栈的大小
 * 因为在hotspot虚拟机上不区分虚拟机栈和本地方法栈
 */
public class StackOverFlow {
    private static volatile int count = 0;

    private static void  testStackOverFlow(){
        ++count;
        System.out.println(count);
        testStackOverFlow();
    }

    public static void main(String[] args) {
        try{
            System.out.println("===="+count);
            testStackOverFlow();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

栈内存溢出异常信息如下

 


 

3、String.intern方法介绍

 

package com.lyzx.jvm;

public class MethodAreaOutOfMemory {

    /**
     * String.intern()方法的作用,
     * 如果字符串A在常量池中已经包含一个和A这个String对象A'的字符串,则返回常量池中字符串的引用A'
     * 否则返回字符串A的引用
     *
     * 下面的这段代码在jdk6,和jdk7中执行不一样,答案是false、true、false
     * 第一个返回false:
     *   java这个常量在虚拟机启动时就已经存在于jvm常量池中,
     *   所以s1.intern()返回的是常量池中的对象的引用,而s1指向的java堆内存中的对象
     * 第二个返回true
     *   计算机这个字符串在常量池中不存在,所以s2.intern()返回的是s2指向的对象,
     *   即s2和s2.intern()执行同一个对象,调用intern()之后jvm会把s2代表的字符串拷贝到常量池中
     * 第三个返回true和第一个同理
     */
    public static void internTest(){
        String s1 = new StringBuilder("ja").append("va").toString();
//        String s1 = new StringBuffer("java").toString();
        System.out.println(s1 == s1.intern());

        String s2 =new StringBuilder("计算").append("计").toString();
        System.out.println(s2 == s2.intern());

        String s3 =new StringBuilder("计算").append("计").toString();
        System.out.println(s3 == s3.intern());
    }

    public static void main(String[] args) {
        internTest();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值