03-JVM内存模型:堆与方法区
一、堆(Heap)
1.1.什么是堆
- 堆在逻辑上划分为“新生代”和“老年代”。由于JAVA中的对象大部分是朝生夕灭,还有一小部分能够长期的驻留在内存中,为了对这两种对象进行最有效的回收,将堆划分为新生代和老年代,并且执行不同的回收策略。不同的垃圾收集器对这2个逻辑区域的回收机制不尽相同,在后续的章节中我们将详细的讲解。
- 堆占用的内存并不要求物理连续,只需要逻辑连续即可。
- 堆一般实现成可扩展内存大小,使用“-Xms”与“-Xmx”控制堆的最小与最大内存,扩展动作交由虚拟机执行。但由于该行为比较消耗性能,因此一般将堆的最大最小内存设为相等。
- 堆是所有线程共享的内存区域,因此每个线程都可以拿到堆上的同一个对象。
- 堆的生命周期是随着虚拟机的启动而创建。

1.2.堆异常
/**
* java堆溢出demo
* JVM参数:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
* Created by chenjunyi on 2018/4/25.
*/
public class HeapOOM { static class OOMObject {
} public static void main(String[] args) {
List<OOMObject> list = new ArrayList<>();
//不断创建新对象,使得Heap溢出
while (true) {
list.add(new OOMObject());
}
} }
上述代码中对象不断的被创建而不进行引用释放,导致GC无法回收堆内存,最终OutOfMemoryError,错误信息:
java.lang.OutOfMemoryError: Java heap space
二、方法区(Method Area)
2.1.什么是方法区


(2)class/method/field等元数据对象:字节码加载之后,JVM会根据其中的内容,为这个类生成Class/Method/Field等对象,它们用于描述一个类,通常在反射中用的比较多。不同于存储在堆中的java实例对象,这两种对象存储在方法区中。
(3)static-final常量、static变量:对于这两种类型的类成员,JVM会在方法区为它们创建一份数据,因此同一个类的static修饰的类成员只有一份;
(4)jit编译器的编译结果:以hotspot虚拟机为例,其在运行时会使用JIT即时编译器对热点代码进行优化,优化方式为将字节码编译成机器码。通常情况下,JVM使用“解释执行”的方式执行字节码,即JVM在读取到一个字节码指令时,会将其按照预先定好的规则执行栈操作,而栈操作会进一步映射为底层的机器操作;通过JIT编译后,执行的机器码会直接和底层机器打交道。如下图所示:


2.2.运行时常量池
//使用StringBuilder在堆上创建字符串abc,再使用intern将其放入运行时常量池
String str = new StringBuilder("abc");
str.intern();
//直接使用字符串字面量xyz,其被放入运行时常量池
String str2 = "xyz";
2.3.方法区的实现
2.4.方法区异常
/**
* java方法区溢出OutOfMemoryError(JVM参数适用于JDK1.6之前,借助CGLIB)
* JVM参数:-XX:PermSize=10M -XX:MaxPermSize=10M
* Created by chenjunyi on 2018/4/26.
*/
public class JavaMethodAreaOOM { public static void main(String[] args) {
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMObject.class);
enhancer.setUseCache(false);
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> methodProxy.invokeSuper(objects, args));
enhancer.create();
}
} static class OOMObject {
} }
Caused by: java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.defineClass1(Native Method)
···
03-JVM内存模型:堆与方法区的更多相关文章
- jvm内存模型(运行时数据区)
运行时数据区(runtime data area) jvm定义了几个运行时数据区,这些运行时数据区存储的数据,供开发者的应用或者jvm本身使用.按线程共享与否可以分为线程间共享和线程间独立. 线程间独 ...
- JVM内存模型——堆(heap)、栈(stack)和方法区(method)
JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区:堆内存用于存放由new创建的对象和数组.堆是JVM管理的内存中最大的一块,堆被所有线程共享,目的 ...
- 1、JVM 内存模型+运行时数据区+JVM参数
JMM(内存模型) 1.’主内存+每个线程有自己的内存 JVM运行时数据区 包含:1.程序计算器(每个线程自带):2.JAVA-STACK(每个线程自带):3.本地方法stack:4.堆:5.方法区 ...
- Java面试- JVM 内存模型讲解
经常有人会有这么一个疑惑,难道 Java 开发就一定要懂得 JVM 的原理吗?我不懂 JVM ,但我照样可以开发.确实,但如果懂得了 JVM ,可以让你在技术的这条路上走的更远一些. JVM 的重要性 ...
- 深入理解JVM - JVM内存模型
各版本的差异 JDK1.6 在JDK1.6 的时候运行时常量池在方法区中 JDK1.7 在JDK1.7 的时候运行时常量池在堆中 JDK1.8 在JDK1.8 的时候,JVM内存模型直接将方法区移到了 ...
- 转:JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )
原文地址:JVM 内存初学 (堆(heap).栈(stack)和方法区(method) ) 博主推荐 深入浅出JVM 这本书 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(heap).栈( ...
- Java 底层机制(JVM/堆/栈/方法区/GC/类加载)
转载:https://www.jianshu.com/p/ae97b692614e?from=timeline JVM体系结构 JVM是一种解释执行class文件的规范技术. JVM体系结构 我翻 ...
- java中栈内存与堆内存(JVM内存模型)
java中栈内存与堆内存(JVM内存模型) Java中堆内存和栈内存详解1 和 Java中堆内存和栈内存详解2 都粗略讲解了栈内存和堆内存的区别,以及代码中哪些变量存储在堆中.哪些存储在栈中.内存中的 ...
- [转载]JAVA内存分析——栈、堆、方法区 程序执行变化过程
面向对象的内存分析 参考:http://www.sxt.cn/Java_jQuery_in_action/object-oriented.html :尚学堂JAVA300集-064内存分析详解_栈_堆 ...
- JVM内存模型以及堆分配参数
程序计数器: 存放下一条要运行的指令:每个线程都必须用一个独立的程序计数器,用于记录下一条要运行的指令.程序计数器是一块线程私有的内存空间. JAVA虚拟机栈: 线程私有的内存空间,它保存方法的局部变 ...
随机推荐
- JDBC(3)ResultSet
ResultSet 在执行查询(select)时候使用 这是一个结果对象,该对象包含结果的方法但指针定位到一行时 调用Statement 对象的 executeQuery(sql)可以得到结果集 可以 ...
- 如何解决“当前上下文中不存在名称“XXXXXXXX””的问题
如果你是用的Visual Studio 2017,如果你项目中的.cshtml文件出现编译调试一切正常,但是在设计时查看出现下面的提示时: 错误 CS0103 当前上下文中不存在名称“ViewBag” ...
- __future__模块
Python提供了__future__模块,把下一个新版本的特性导入到当前版本,于是我们就可以在当前版本中使用一些新版本的特性,比如除法: 在Python 2.x中,对于除法有两种情况,如果是整数相除 ...
- iOS数据存储类型 及 堆(heap)和栈(stack)
iOS数据存储类型 及 堆(heap)和栈(stack) 一般认为在c中分为这几个存储区: 1栈 -- 由编译器自动分配释放. 2堆 -- 一般由程序员分配释放,若程序员不释放,程序结束时可能由O ...
- OSD仿真_MFC程序01
Windows系统具有强大的绘图功能,可以用来模拟OSD显示.接下来将设计一个简单的模拟显示终端的程序,用于后续显示功能和菜单系统的开发.说明一下,对于Windows下的MFC编程我不怎么了解,只知道 ...
- Linux在线安装jdk8,并配置环境变量
1.创建相关目录:下载目录.安装目录 下载目录: cd / 2.下载jdk8到目录 下载前先跳转到下载目录,比如希望最后压缩包下载到/home/bak/下, 则先创建bak目录,命令如下: 注意:如果 ...
- es6新特性之 class 基本用法
javaScript 语言中,生成实例对象的传统方法是通过构造函数,与传统的面向对象语言(比如 C++ 和 Java)差异很大,ES6 提供了更接近传统语言的写法,引入了 class(类)这个概念,作 ...
- 【reidis中ruby模块版本老旧利用rvm来更新】
//gem install redis时会遇到如下的error: //借助rvm来update ruby版本
- tomcat安装、配置相关的几个点
Connector port="8080"HTTP协议的默认端口号:8080 FTP协议的默认端口号:21 1.tomcat的安装目录要与Java jre的安装目录一致. bin: ...
- 关于instanceof的使用
测试单独一个类: <?php class A { } $a = new A(); if($a instanceof A){ echo "对象\$a实现了A类"; } 当一个子 ...