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

从sample来学习Java堆(转)的更多相关文章

  1. 从几个sample来学习JAVA堆、方法区、JAVA栈和本地方法栈

    最近在看<深入理解Java虚拟机>,书中给了几个例子,比较好的说明了几种OOM(OutOfMemory)产生的过程,大部分的程序员在写程序时不会太关注Java运行时数据区域的结构: 感觉有 ...

  2. JVM学习--(八)java堆分析

    上一节介绍了针对JVM的监控工具,包括JPS可以查看当前所有的java进程,jstack查看线程栈可以帮助你分析是否有死锁等情况,jmap可以导出java堆文件在MAT工具上进行分析等等.这些工具都非 ...

  3. java基础学习之"堆" "栈" "静态存储区" "方法区"

    引用部分 java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来) Java堆.栈和常量池以及相关String的讲解 等我看完"深入理 ...

  4. 如何学习Java?

    一点感悟 java作为一门编程语言,在各类编程语言中作为弄潮儿始终排在前三的位置,这充分肯定了java语言的魅力,在实际项目应用中,我们已经无法脱离javaa(Ps当然你可以选择不使用),但它的高性能 ...

  5. 应用JConsole学习Java GC

    应用JConsole学习Java GC 关于Java GC的知识,好多地方都讲了很多,今天我用JConsole来学习一下Java GC的原理. GC原理 在我的上一篇中介绍了Java运行时数据区,在了 ...

  6. 用Robocod游戏来学习JAVA

    Robocode(用游戏来学习Java技术还是用Java来玩游戏?)用你的JAVA编程技术来玩游戏吧!不会JAVA?那就用游戏来学习JAVA吧!什么是Robocode? 其实我对机器人一直很感兴趣.我 ...

  7. 优化Java堆大小5温馨提示

    总结:Java没有足够的堆大小可能会导致性能非常大的影响,这无疑将给予必要的程序,并不能带来麻烦.本文总结了影响Java居前五位的能力不足,并整齐地叠优化? 笔者Pierre有一个10高级系统架构师有 ...

  8. Java堆和栈的区别和介绍,JVM的堆和栈

    一.Java的堆内存和栈内存 Java把内存划分成两种:一种是堆内存,一种是栈内存.   堆:主要用于存储实例化的对象,数组.由JVM动态分配内存空间.一个JVM只有一个堆内存,线程是可以共享数据的. ...

  9. 浅谈Java堆内存分代回收

    目录 1.概述 2.堆内存是如何分代的 3.各分代之间是如何配合工作的 1.概述 与C++不同的是, 在Java中我们无需关心对象占用空间的释放, 这主要得益于Java中的垃圾处理器(简称GC)帮助我 ...

随机推荐

  1. Android 设置 横屏 竖屏

    方法一:在AndroidManifest.xml中配置 如果不想让软件在横竖屏之间切换,最简单的办法就是在项目的AndroidManifest.xml中找到你所指定的activity中加上androi ...

  2. 开源欣赏wordpress之post.php

    switch($action) { case 'postajaxpost': case 'post': case 'post-quickpress-publish': case 'post-quick ...

  3. spring-boot+nginx+tomcat+ssl配置笔记

    如果你的tomcat应用需要采用ssl来加强安全性,一种做法是把tomcat配置为支持ssl,另一种做法是用nginx反向代理tomcat,然后把nginx配置为https访问,并且nginx与tom ...

  4. Java根据年份算出所属的生肖。

    一个小程序~ public String getYear(Integer year){ if(year<1900){ return "未知"; } Integer start ...

  5. linux 之 tar 命令

    通过SSH访问服务器,难免会要用到压缩,解压缩,打包,解包等,这时候tar命令就是是必不可少的一个功能强大的工具.linux中最流行的tar是麻雀虽小,五脏俱全,功能强大. tar 命令可以为linu ...

  6. February 29(模拟)

    D - D Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status P ...

  7. 左右HttpClient上传的方法来解决中国的乱码

    二手HttpClient人们都知道通过addTextBody方法来加入要上传的文本信息,可是,假设要上传中文的话.或还有中文名称的文件会出现乱码的问题,解决的方法事实上非常easy: 第一步:设置Mu ...

  8. Android应用程序组件Content Provider在应用程序之间共享数据的原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6967204 在Android系统中,不同的应用 ...

  9. Ascll

    ascll - 概述 ASCII码(American Standard Code for Information Interchange, 美国标准信息交换码).   信息编码就是将表示信息的某种符号 ...

  10. Bootstrap的datepicker控件

    为input 控件的text 添加datepicker()方法后,原本的控件change事件无法正常触发.原因是项目中同时使用了用了jquery ui,碰巧它里面也有一个datepicker,名字一模 ...