jvm小总结

2019-02-13  本文已影响0人  f22448cd5541

为什么要了解JVM

作为java 程序员开发,如果想要更好的优化程序的话,必须要对jvm的整个原理非常了解,这样才能在高并发的场景中,根据自己的业务需求去配置相应的jvm。

jvm内存分配

从功能角度来考虑jvm内存划分可以分为:

注: 程序计数器、虚拟机栈、本地方法栈 随着线程而生,随着线程结束而灭。

常用的jvm参数

线程OOM(java.lang.OutOfMemoryError)

-Xss10M 固定的时候,每启动一个线程的时候就会占用虚拟机栈的空间,所以每个线程分配的虚拟机栈的容量越大,那么能够启动的线程数就越少。

代码演示:

/**
 * <p>
 *      测试虚拟机栈 java.lang.OutOfMemoryError
 * </p>
 *
 * @author robinyang
 * @date 2018.10.03
 *
 * @see StackOverflowError
 */
public class Test04 {

    public static void main(String[] args) {
        for (int i = 0; i < 1000; i++) {
            new Thread(new OOMThread()).start();
            System.out.println(i);
        }
    }


    public static class OOMThread implements Runnable {

        public void run() {
            byte[] bytes = new byte[10240];
            try {
                Thread.sleep(100000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

当启动七百多的时候就会出现:

Exception in thread "Thread-757" Exception in thread "Thread-761" 
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
Exception in thread "Thread-758" Exception in thread "Thread-760" Exception in thread "Thread-762" Exception in thread "Thread-763" *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message can't create byte arrau at JPLISAgent.c line: 813

增强类导致OOM

方法区一般存放的是Class相关信息,比如 类名、访问修饰符、常量池、字段描述、方法描述等。想要测试这些区域OOM 可以通过产生大量类去填充方法区即可。可以通过动态反射和CGLib可以产生大量的动态类。

总结:在一些框架,如:SpringHibernate等等,在对类进行增强的时候,经常会产生很多类,类越多,导致方法区的内存占用比较大,出现OOM。还有jvm上的动态语言为了实现动态特性会持续创建类,也会导致方法区内存占用过大,出现OOM。

直接内存默认值

DirectMemory 这块内存跟元数据的直接内存是两块不一样的内存,这里的内存可以存放我们程序运行时的数据。当我们不设置直接内存大小的时候,默认和Java堆内存一样大小 -Mmx5M 一样大。

当然,我们可以直接设置堆外内存: -XX:MaxDirectMemorySize=10M

上一篇 下一篇

猜你喜欢

热点阅读