zoukankan      html  css  js  c++  java
  • java内存总结

    一、java内存分区

    一共分为6个区域:

    1、方法区(也叫非堆区)和堆区,另外还有直接内存即堆外内存,这三个区域都是线程共享的内存区域。

    2、虚拟机栈,本地方法栈,程序计数器。

    这6个区域,出了程序计数器区域不可能发生内存问题,其他5个区域都可能发生内存问题。

    这里指的内存问题包括内存泄漏和内存溢出。

    内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;

    内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

    二、各区内存报错分类

    1、虚拟机栈

    虚拟机栈区域存放的是函数参数,动态链接,方法出口,局部变量表等等栈帧信息。

    这个区域通常发生内存溢出,比如死循环,递归深度过深就会报错:StackOverflowError

    另外极少情况下,栈内存不够用,才会出现OutOfMemeroyError

    2、本地方法栈

    这个区域和虚拟机栈非常类似,唯一区域是本地方法栈是为跨语言调用设计的。

    一般的java程序员用得很少,一般在跨语言调用时出现,当java调用C的动态链接库里面的方法时,就会出现和虚拟机栈内存溢出一样的两种报错

    3、Java堆

    这个区域报错很常见,大量的java对象就存在这里。

    这个区域中可以支持划分出部分给每个线程独享,叫Thread Local Allocation Buffer即TLAB。

    内存溢出时,只会抛出OutOfMemoryErro异常

    4、方法区

    这个区域存放java类里面静态变量,常量,类加载信息,即时编译信息等。是线程共享的内存区域。也叫非堆(Non-Heap)

    这个区域是用永久代的方式进行内存管理。也就是说只有触发Full GC才会回收。通常回收条件苛刻,一旦有问题,很容易内存报错。

    内存溢出是,会抛出OutOfMemoryErro异常

    另外运行时常量池是方法区的一部分。比如:

    String a = "sdfdfsd" ;

    String b = "sdfdfsd" ;

    直接赋值字符串是在堆里申请空间,把引用存入常量池 ,

    当再次赋值时,JVM会判断常量池中是否已经存在,如果存入,不会再到堆申请内存,而是直接返回其引用。所以 a == b 是true

    String c = new String("sdfsdf");

    String d = new String("sdfsdf");

    这个就是完全在堆里。由于c和d是不同的指针,指向的内存区域不一致,所以c == d 为false

    5、直接内存(堆外内存)

    这个区域也是容易发生内存溢出。通常是在使用JDK的NIO的方法时用到。

    HeapByteBuffer heapByteBuffer     = ByteBuffer.allocate(1024);
    DirectByteBuffer directByteBuffer = ByteBuffer.allocateDirect(1024);

    这段代码只是为了说明区别,其实HeapByteBuffer 和 DirectByteBuffer是ByteBuffer的内部类,不能被外部引用。上面的代码是不能用的。

    allocateDirect就是用的是堆外内存,即当前java进程外部的操作系统剩余内存

    allocate是申请java当前进程的正常堆区的内存

    控制堆外内存的参数是: -XX: MaxDirectMemorySize,不指定时,和-Xmx即堆空间一样大小。

    堆外内存溢出有一个明显特征:

    在HeapDump文件中不会看见明显的异常,而且Dump文件很小。并且程序中直接或者间接使用了堆外内存。

    比如spark1.6以后版本,在shuffer阶段各节点使用netty进行传输磁盘文件数据,很容易堆外内存溢出。

    这次写到这里。

     

  • 相关阅读:
    服务部署 RPC vs RESTful
    模拟浏览器之从 Selenium 到splinter
    windows程序设计 vs2012 新建win32项目
    ubuntu python 安装numpy,scipy.pandas.....
    vmvare 将主机的文件复制到虚拟机系统中 安装WMware tools
    ubuntu 修改root密码
    python 定义类 简单使用
    python 定义函数 两个文件调用函数
    python 定义函数 调用函数
    python windows 安装gensim
  • 原文地址:https://www.cnblogs.com/geektcp/p/9930890.html
Copyright © 2011-2022 走看看