Java虚拟机读书笔记1——内存区域划分

Java 和 C++之间有一堵墙,墙里的人想出来,墙外的人想进去,这堵墙就是内存分配与垃圾回收(说实话,之前主要用c++,从来不想进去,在美国的一家小公司要用java,不进去也不行了)

1 内存区域的划分,java内存区域的划分远比c++要复杂的多, c++ 中也就分成: 栈 堆 代码区域 数据区域 静态全局区域(根据是否初始化还能再分成两类) 

1.1 程序计数器:每个线程分配一个计数器,计数器中保存着当前线程运行的程序地址(可能是函数的静态下标,也可能是程序字节码地址)

1.2 Java虚拟机栈:存储局部变量,函数内声明的变量,int double string 指向对象的引用等等

1.3 本地方法栈:当java需要调用其他语言编写的程序时,需要使用关键字native修饰一个方法,这个方法称为本地方法,本地方法的地址存储在本地方法栈中

1.4 Java堆:划分为new generation 和old generation;

new generation 中保存是生命周期较短的小对象,在minor GC过程中就会被回收,new generation 将80%的内存划分为Eden区域, 另划分两个区域各自占10% 叫做survivor 区域。新创建出来的对象放在Eden中,GC后活下来的对象移动到survivor 中

old generation 长声明周期的对象 

一次fullGC的过程:创建太多对象 ->Eden内存不足 -> 对象移动到old generation ->old 满了->full GC

1.5 方法区: 存储类信息 常量 静态变量,也叫permnent generation

1.6 运行时常量池:存放字面值与符号引用

1.7 直接内存:java虚拟机以外的内存,用于与外界进行交互

2 将每一块内存搞爆的方法:

1)将堆搞爆的方法:

List<String> li = new ArrayList<String>();

while(true) li.add(new String());

2) 将栈搞爆,递归函数地址存在栈中

class OOM {

  private int c = 1;

  public void cur() {

       c++; cur();

      }

     main() {

         cur();

     }

}

3) 将常量区域搞爆:

List<String> li = new ArrayList<String>();

int i = 0;

while(true) li.add(String.valueOf(i++).intern());

猜你喜欢

转载自www.cnblogs.com/jiasenhuo/p/9644354.html