从sample来学习Java堆(转)

简介: 1)Java堆  所有对象的实例分配都在Java堆上分配内存,堆大小由-Xmx和-Xms来调节,sample如下所示:    public class HeapOOM {  static class OOMObject{}  /**  * @param args  */  public static...

1)Java堆
  所有对象的实例分配都在Java堆上分配内存,堆大小由-Xmx和-Xms来调节,sample如下所示:
  
  public class HeapOOM {
  static class OOMObject{}
  /**
  * @param args
  */
  public static void main(String[] args) {
  List<OOMObject> list = new ArrayList<OOMObject>();
  while(true){
  list.add(new OOMObject());
  }
  }
  }
  加上JVM参数-verbose:gc -Xms10M -Xmx10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+HeapDumpOnOutOfMemoryError,就能很快报出OOM:
  Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
  并且能自动生成Dump.
2)方法区
  方法区是存放虚拟机加载类的相关信息,如类、静态变量和常量,大小由-XX:PermSize和-XX:MaxPermSize来调节,类太多有可能撑爆永久带:
  
  public class MethodAreaOOM {
  static class OOMOjbect{}
  /**
  * @param args
  */
  public static void main(String[] args) {
  // TODO Auto-generated method stub
  while(true){
  Enhancer eh = new Enhancer();
  eh.setSuperclass(OOMOjbect.class);
  eh.setUseCache(false);
  eh.setCallback(new MethodInterceptor(){
  @Override
  public Object intercept(Object arg0, Method arg1,
  Object[] arg2, MethodProxy arg3) throws Throwable {
  // TODO Auto-generated method stub
  return arg3.invokeSuper(arg0, arg2);
  }
  });
  eh.create();
  }
  }
  }
  加上永久带的JVM参数:-XX:PermSize=10M -XX:MaxPermSize=10M,运行后会报如下异常:
  Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
  静态变量或常量也会有可能撑爆方法区:
  
  public class ConstantOOM {
  /**
  * @param args
  */
  public static void main(String[] args) {
  // TODO Auto-generated method stub
  List<String> list = new ArrayList<String>();
  int i=0;
  while(true){
  list.add(String.valueOf(i++)。intern());
  }
  }
  }
  同样加上JVM参数:-XX:PermSize=10M -XX:MaxPermSize=10M,运行后报如下异常:
  Exception in thread "main" java.lang.OutOfMemoryError: PermGen space

  3)Java栈和本地方法栈
  栈是存放线程调用方法时存储局部变量表,操作,方法出口等与方法执行相关的信息,栈大小由Xss来调节,方法调用层次太多会撑爆这个区域,samples如下所示:
  
  package com.cutesource;
  public class StackOOM {
  /**
  * @param args
  */
  private int stackLength = 1;
  public void stackLeak(){
  stackLength++;
  stackLeak();
  }
  public static void main(String[] args) throws Throwable{
  // TODO Auto-generated method stub
  StackOOM oom = new StackOOM();
  try{
  oom.stackLeak();
  }catch(Throwable err){
  System.out.println("Stack length:" + oom.stackLength);
  throw err;
  }
  }
  }
  设置JVM参数:-Xss128k,报出异常:
  Exception in thread "main" java.lang.StackOverflowError
  打印出Stack length:1007,这里可以看出,在我的机器上128k的栈容量能承载深度为1007的方法调用。当然报这样的错很少见,一般只会出现无限循环的递归中,另外,线程太多也会占满栈区域:
  
  package com.cutesource;
  public class StackOOM {
  /**
  * @param args
  */
  private int stackLength = 1;
  private void dontStop(){
  while(true){
  try{Thread.sleep(1000);}catch(Exception err){}
  }
  }
  public void stackLeakByThread(){
  while(true){
  Thread t = new Thread(new Runnable(){
  @Override
  public void run() {
  // TODO Auto-generated method stub
  dontStop();
  }
  });
  t.start();
  stackLength++;
  }
  }
  public static void main(String[] args) throws Throwable{
  // TODO Auto-generated method stub
  StackOOM oom = new StackOOM();
  try{
  oom.stackLeakByThread();
  }catch(Throwable err){
  System.out.println("Stack length:" + oom.stackLength);
  throw err;
  }
  }
  }
  报出异常:Exception in thread "main" java.lang.OutOfMemoryError:unable to create new native thread
  不过在windows上运行这个例子要小心,会出现系统假死的情况,有可能需要重启机器才行。
  以上几个例子虽然比较简单,但能很好帮助普通的程序员更加直观的了解Java堆,方法区,Java栈和本地方法栈。

 

http://www-01.ibm.com/support/knowledgecenter/SS3KLZ/com.ibm.java.diagnostics.memory.analyzer.doc/gcroots.html

相关文章
|
8天前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
15 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
|
11天前
|
存储 算法 Java
🏗️Java零基础:深入了解Java 堆
【10月更文挑战第2天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
16 3
|
8天前
|
小程序 Oracle Java
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
这篇文章是关于JVM基础知识的介绍,包括JVM的跨平台和跨语言特性、Class文件格式的详细解析,以及如何使用javap和jclasslib工具来分析Class文件。
21 0
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
|
10天前
|
前端开发 Java 应用服务中间件
Javaweb学习
【10月更文挑战第1天】Javaweb学习
21 2
|
13天前
|
存储 缓存 Java
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
27 1
|
13天前
|
存储 搜索推荐 算法
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
18 1
|
13天前
|
算法 Java API
【用Java学习数据结构系列】对象的比较(Priority Queue实现的前提)
【用Java学习数据结构系列】对象的比较(Priority Queue实现的前提)
23 1
|
6天前
|
存储 算法 Java
带你学习java的数组军队列
带你学习java的数组军队列
24 0
|
9天前
|
Java 大数据 开发工具
java学习——环境准备(1)
java学习——环境准备(1)
22 0
|
13天前
|
存储 算法 Java
【用Java学习数据结构系列】用堆实现优先级队列
【用Java学习数据结构系列】用堆实现优先级队列
26 0