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虚拟机栈: 线程私有的内存空间,它保存方法的局部变 ...
随机推荐
- ARP, Fragmentation and Reassembly
Address Resolution Protocol IP addresses are said to be logical, because they are defined in terms o ...
- The App Life Cycle & The Main Function
The App Life Cycle Apps are a sophisticated interplay between your custom code and the system framew ...
- 如何在IAR工程中创建和使用模板
路径为:Edit -> Code Templates -> Edit Templates 如下图: #TEMPLATE "&FileDeclare>&Fi ...
- 再看redux
redux提供了一个全局的唯一状态树,不代表就不需要组建本身的state. 何时用react组件的state.props?? state只表示一些‘临时的’‘内部的’状态数据.临时的:代表你可以临时改 ...
- 不用循环,、es6创建一个长度为100的数组
问题描述:在不使用循环的条件下,如何创建一个长度为100的数组,并且数组的每一个元素是该元素的下标? 结果为: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1 ...
- 系统优化怎么做-JVM优化之开篇
大家好,这里是「聊聊系统优化 」,并在下列地址同步更新 博客园:http://www.cnblogs.com/changsong/ 知乎专栏:https://zhuanlan.zhihu.com/yo ...
- linux 内存操作相关命令
清理内存 echo 1 > /proc/sys/vm/drop_caches 查看内存使用情况 free –m 查看内存条数命令: dmidecode |grep -A16 "Memo ...
- Unity 游戏框架搭建 (二十三) 重构小工具 Platform
在日常开发中,我们经常遇到或者写出这样的代码 var sTrAngeNamingVariable = "a variable"; #if UNITY_IOS || UNITY_AN ...
- Linux下安装 Redis
一.部署前准备 1.首先上官网下载Redis 最新稳定的压缩包 2.通过远程管理工具,将压缩包拷贝到Linux服务器中,执行解压操作 [root@CentOS6 ~]# tar zxvf redis- ...
- LogViewer超大文本浏览工具
官方下载 LogViewer 是一款简单好用的log日志文件查看工具.您想要查看log日志吗?那么不妨来看看这款LogViewer .该款工具可以在短短数秒内打开上G的LOG文件,支持高亮某行文字(例 ...