从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

目录
打赏
0
0
0
0
95
分享
相关文章
8G的容器Java堆才4G怎么就OOM了?
本文记录最近一例Java应用OOM问题的排查过程,希望可以给遇到类似问题的同学提供参考。
Java线程池ExecutorService学习和使用
通过学习和使用Java中的 `ExecutorService`,可以显著提升并发编程的效率和代码的可维护性。合理配置线程池参数,结合实际应用场景,可以实现高效、可靠的并发处理。希望本文提供的示例和思路能够帮助开发者深入理解并应用 `ExecutorService`,实现更高效的并发程序。
38 10
【潜意识Java】深度分析黑马项目《苍穹外卖》在Java学习中的重要性
《苍穹外卖》项目对Java学习至关重要。它涵盖了用户管理、商品查询、订单处理等模块,涉及Spring Boot、MyBatis、Redis等技术栈。
141 4
【潜意识Java】Java基础教程:从零开始的学习之旅
本文介绍了 Java 编程语言的基础知识,涵盖从简介、程序结构到面向对象编程的核心概念。首先,Java 是一种高级、跨平台的面向对象语言,支持“一次编写,到处运行”。接着,文章详细讲解了 Java 程序的基本结构,包括包声明、导入语句、类声明和 main 方法。随后,深入探讨了基础语法,如数据类型、变量、控制结构、方法和数组。此外,还介绍了面向对象编程的关键概念,例如类与对象、继承和多态。最后,针对常见的编程错误提供了调试技巧,并总结了学习 Java 的重要性和方法。适合初学者逐步掌握 Java 编程。
56 1
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
106 5
14天Java基础学习——第1天:Java入门和环境搭建
本文介绍了Java的基础知识,包括Java的简介、历史和应用领域。详细讲解了如何安装JDK并配置环境变量,以及如何使用IntelliJ IDEA创建和运行Java项目。通过示例代码“HelloWorld.java”,展示了从编写到运行的全过程。适合初学者快速入门Java编程。
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
5月前
|
Java学习十六—掌握注解:让编程更简单
Java 注解(Annotation)是一种特殊的语法结构,可以在代码中嵌入元数据。它们不直接影响代码的运行,但可以通过工具和框架提供额外的信息,帮助在编译、部署或运行时进行处理。
130 43
Java学习十六—掌握注解:让编程更简单

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等