转载

Java内存管理笔记

内存模型

1. PC寄存器 Program Counter Register

严格来说是一种数据结构,用于保存当前正常执行的程序的内存地址,来保证中断时只能能继续执行下去。

根据jvm规范,在这个区域中不会抛出OutOfMemoryError的内存异常。

2. Java栈 Java stack

这个区域是最容易出现内存异常的区域,每一个线程对应生成一个线程栈,线程每执行一个方法的时候,都会创建一个栈帧(Frames),用来存放方法的局部变量表,操作栈,动态连接,方法返回值等信息。

jvm规范对这个区域定义了两种内存异常,OutOfMemoryError,StackOverflowError。

命令设置方式:

-Xss

3. 本地方法栈 Native Method Stack

和虚拟机栈一样,不同的是处理的对象不一样,虚拟机栈处理java的字节码,而本地栈则是处理的Native方法。其他方面一致。

命令设置方式:

-XX:PermSize=2M

-XX:MaxPermSize=2M

4. 堆 Heap

堆是所有线程都能访问的,随着虚拟机的启动而存在,这块区域很大,因为所有的线程都在这个区域保存实例化的对象,因为每一个类型中,每个接口实现类需要的内存不一样,一个方法内的多个分支需要的内存也不尽相同,我们只有在运行的时候才能知道要创建多少对象,需要分配多大的地址空间。

GC关注的正是这样的部分内容,所以很多时候也将堆称为GC堆。

堆中肯定不会抛出StackOverflowError类型的异常,所以只有OutOfMemoryError相关类型的异常。 

命令设置方式:

-Xms(堆的最小值) 

-Xmx(堆的最大值)

5. 方法区 Method Area

用于存放已被虚拟机加载的类信息,常量,静态方法,即使编译后的代码。

同样只能抛出OutOfMemoryError相关类型的异常。

内存问题

1. 内存溢出 out of memory

定义:是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

原因:

  • 内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
  • 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
  • 代码中存在死循环或循环产生过多重复的对象实体;
  • 使用的第三方软件中的BUG;
  • 启动参数内存值设定的过小。

2. 内存泄露 memory leak

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

参考:

1. 《深入分析 Java Web技术内幕》 许令波

2. 《Java高并发编程详解》 汪文君

3. 《内存溢出的解决思路》 www.cnblogs.com/200911/p/39…

原文  https://juejin.im/post/5dc145916fb9a04a5d5864cb
正文到此结束
Loading...