打算花比较长的篇幅来描述下自己理解的JVM,尽量描述的清晰易懂一些,从简单慢慢到慢慢深入,一方面自己也复习一下,一方面也供大家参考,少走些弯路。鉴于本人水平有限,如有错误的地方,欢迎指出,感谢。

一段废话引出,大家都知道java有JVM,那JVM有个非常方便的自动内存管理机制,致使java开发人员不再需要为每个new操作去写配对的delete/free代码,而且不容易出现内存泄漏和内存溢出的问题(不容易并非不可能),不过真因为此一旦出现了内存泄漏或者溢出的问题,如果不了解JVM怎么样使用内存的,那么排查起来也会比较困难。

我们初始学习java时候很多人关注就是java的堆栈,这种分法比较粗糙,但是易与理解,实际上远远不止于此,但是今天我们就先按粗浅的方式去解释下,后面我们在逐步深入。按我的习惯,我们先看个例子。

1 public class BaseTest {
2     public static void main(String[] args) throws Exception{
3         ArrayList list=new ArrayList();
4         while(true){
5             list.add(new FinalBean());
6         }
7     }
8 }

上面这段代码最终的结果:

1 java.lang.OutOfMemoryError: GC overhead limit exceeded
2 Dumping heap to java_pid1288.hprof ...
3 Heap dump file created [34835053 bytes in 0.247 secs]
4 Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
5     at java.util.Arrays.copyOf(Arrays.java:3332)
6     at java.lang.String.concat(String.java:2032)
7     at com.cz.smart.center.FinalBean.<init>(FinalBean.java:13)
8     at com.cz.smart.center.BaseTest.main(BaseTest.java:14)

为什么会出现这种结果呢?

我们通过创建实例对象 new FinalBean(),会开辟堆内存空间,往list列表里面加,导致实例对象没法回收,一直到无法申请到新的内存,导致爆内存溢出,那有没有考虑过,为什么实例对象的内存无法进行回收呢?

再看一个例子

public class BaseTest {int i = 0;public static void main(String[] args) throws Exception{BaseTest b = new BaseTest();b.addStackLength();}public void addStackLength(){i++;        System.out.println(i);addStackLength();}
}

上面这段代码最终的结果:

938
939
Exception in thread "main" java.lang.StackOverflowErrorat sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)at sun.nio.cs.UTF_8.access$200(UTF_8.java:57)at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:636)at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)at java.io.PrintStream.write(PrintStream.java:526)at java.io.PrintStream.print(PrintStream.java:597)at java.io.PrintStream.println(PrintStream.java:736)

  

为什么这段代码会报这个错呢?StackOverflowError 栈溢出错误。

递归调用,死循环,超过栈的深度,导致抛出异常,那这段代码再内存从怎么跑的呢?我画图解释下:

我们知道栈是线程独享的,每个线程都会有自己独立的栈,而每调用一个方法会产生一个栈针进行入栈。

1.在代码b.addStackLength 时候,会入栈addStackLength方法的栈针,栈针包括局部变量表,操作数栈,动态链接,方法出口等信息(这些后面会详细讲解)。

2.进入方法addStackLength的时候,先执行i++,然后输出i++信息,发现该方法又调用了addStackLength的方法。

3.于是又会入栈一个addStackLength方法的栈针,以此循环,由于是死循环,入栈的栈针超过了栈的深度,抛出StackOverflowError 错误。

注:如果是递归调用而没有死循环,那情况就是在最底层的方法执行完之后,最底层方法就会出栈,调转到上一个调用该方法的下一行,以此类推持续出栈,这就是栈的先入后出。

后续一步步拆分堆和栈内容信息,未完待续。。。

转载于:https://www.cnblogs.com/HA-Tinker/p/10687097.html

Java 内存模型(一)相关推荐

  1. 从底层吃透java内存模型(JMM)、volatile、CAS

    前言 随着计算机的飞速发展,cpu从单核到四核,八核.在2020年中国网民数预计将达到11亿人.这些数据都意味着,作为一名java程序员,必须要掌握多线程开发,谈及多线程,绕不开的是对JMM(Java ...

  2. 循序渐进:带你理解什么是Java内存模型

    近期笔者在阅读<深入理解Java虚拟机:JVM高级特性与最佳实现(第3版)>,书中提到关于Java内存模型的知识点,但是看完之后还是感觉有些模糊,便查阅一些其他相关资料.本文是笔者经过对知 ...

  3. java并发编程实战:第十六章----Java内存模型

    一.什么是内存模型,为什么要使用它 如果缺少同步,那么将会有许多因素使得线程无法立即甚至永远看到一个线程的操作结果 编译器把变量保存在本地寄存器而不是内存中 编译器中生成的指令顺序,可以与源代码中的顺 ...

  4. JSR 133 Java内存模型以及并发编程的最权威论文汇总

    Java内存模型 先看官方文档: https://docs.oracle.com/javase/specs/ JSR 133:Java TM内存模型和线程规范修订版:https://www.jcp.o ...

  5. java线程的优先级是数字越大优先级越高_《深入理解Java虚拟机》5分钟速成:12章(Java内存模型与线程)...

    第12章 Java内存模型与线程 前言: 1.物理机如何处理并发问题? 2.什么是Java内存模型? 3.原子性.可见性.有序性的具体含义和应用实现? 4.volatile 关键字特性? 5.基于vo ...

  6. Java内存模型与线程

    一.一致性 高速缓存的存储交互很好的解决了处理器与内存的速度矛盾,但也存在缓存一致性(cache coherence)问题 二.java内存模型 内存模型:对特定的内存或高速缓存进行读写访问的过程抽象 ...

  7. java内存模型-JMM

    java内存模型 转载于:https://www.cnblogs.com/our880tom/p/6679068.html

  8. 深入理解Java内存模型(四)——volatile

    2019独角兽企业重金招聘Python工程师标准>>> volatile的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别.理解volatile特性的一个好 ...

  9. java和内存交互,java内存模型-内存间交互操作

    前言 本文是阅读周志明大佬的<深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)>第12章,12.3节Java内存模型得来的读书笔记. 阅读告警

  10. 也许,这是东半球最叼的Java内存模型

    面试官:你好,你先自我介绍一下. 安琪拉:面试官你好,我叫安琪拉,草丛三婊,最强中单,草地摩托车车手,第21套广播体操推广者,火球拥有者.不焚者,安琪拉,这是我的简历,请过目. 面试官:看你简历上写熟 ...

最新文章

  1. cv::cuda::split 使用
  2. Visual Studio原生开发的20条调试技巧(下)
  3. SUSE下使用syslog-ng部署日志服务器
  4. python继承如何进行引用传递的区别_python在什么情况下会引用传递呢?
  5. Java 反射取类中类_Java反射机制(二):通过反射取得类的结构
  6. 车载系统华山论剑:Ali OS、Android、QNX孰优孰劣
  7. 关于WIN10显示“未安装任何音频输出设备” 英特尔(R)智音系统OED启动错误(代号10)解决办法
  8. 基于单片机的KTV智能调光系统设计
  9. 苹果发布的Mac Pro就是“渣渣”?网友疯狂吐槽
  10. 對Googgle adsense廣告作弊和Googeladsense點擊廣告的生存前景看法
  11. 最近的收获以及清明节的安排
  12. 杀毒软件工作原理及现有主要杀毒技术
  13. 基于Java+SpringBoot+Thymeleaf+Mysql在线外卖点餐系统设计与实现
  14. 完美解决网页中Flash狂闪的问题
  15. java导出word加水印(已实现)
  16. php无法访问_php突然不能访问的原因
  17. 董氏奇穴学习记录(上课记录)
  18. 第2章 C语言的赋值运算符、复合运算符与逗号运算符 (十一)
  19. vue的侦听器,过滤器和过度动画的了解
  20. web 页面 常用分辨率(PC 移动端)

热门文章

  1. tyvj 2002 扑克牌
  2. javaScript初学笔记(二)
  3. (转载)网络编程释疑之:同步,异步,阻塞,非阻塞
  4. OpenGL——使用Bresenham算法绘制圆
  5. 至于你信不信,我反正是信了——以类为单位的编程思想
  6. C#将照片或图片转化为byte[]存入数据库,从数据库中读照片
  7. [转]谨以此文献给才毕业2--5年的朋友
  8. atlas和ajaxpro以及微软企业级类库在一起得web配置文件
  9. .net快速入门方法,转csdn
  10. qt for 3520a