jvm内存区域与溢出

目录

为什么学习jvm

  • 木板原理,最短的一块板决定一个水的深度,当一个系统垃圾收集成为瓶颈的时候,那么就需要你对jvm的了解掌握。
  • 当一个系统出现内存溢出,内存泄露的时候,因为你懂jvm知识,可以更加快速定位错误,可以通过参数去合理设置各内存区域的内存容量。
  • 因为你对jvm的认识,写代码的时候会潜意识地让你注意代码质量,可能你会说是那是小小的性能提升,但是量变会导致质变的。

jvm内存区域

jvm内存划分

  • 方法区
  • 虚拟机栈
  • 本地方法栈
  • 程序计数器

程序计数器

  • 当前线程所执行的字节码的行号指示器。
  • 因为cpu的每个核心只能同时运行一个线程,所以当一个线程执行完时间片后切换到另一个线程,切换时为了能恢复到正确的执行位置,所以需要程序计数器(学过计算机组成原理的应该比较熟悉)。
  • 如果是线程执行的是一个java方法那么此时计数器记录的是正在执行的虚拟机字节码指令的地址。如果是nativ方法(非java代码),计数器值为空。

虚拟机栈

  • java执行的内存模型,栈由栈帧组成,线程调用一个java方法时,创建一个栈帧,方法返回时,栈帧弹出。栈帧入栈出栈的过程就是方法开始结束的过程
  • 栈帧存储局部变量区(存放基本数据类型数据,对象指针),操作数栈(存放操作数,比如加法运算的时候操作数栈取值,计算后再压入栈),动态链接(将符号引用(常量池指向方法的符号引用)转换为调用方法的直接引用),方法出口。

本地方法栈

  • 和虚拟机栈作用类似,只不过服务对象不同,本地方法服务对象是非java方法,虚拟机栈服务对象是java方法

方法区

  • 存放类的信息、常量、静态变量等
  • 运行时常量池是方法区一部分,主要存放字面量(如final修饰的变量)和符号引用量(编译原理方面)

  • 存放对象,对象要在堆上分配内存
  • 堆分为年轻代和年老代
  • 年轻代分为伊甸区(Eden space)和幸存者区(Survivor space)
  • 幸存区分为from和to空间

总结

  • jvm的内存区域划分为程序计数器,虚拟机栈,本地方法栈,方法区,堆。
  • 程序计数器,虚拟机栈和本地方法栈都是线程独享的,而方法区和堆是线程共享的

溢出

理清概念

  • 操作系统分配给进程的内存是有限的,而jvm的内存区域我们已经知道,当我们设置好堆和方法区的最大容量后,那么剩下的内存将分配给虚拟机栈和本地方法区和程序计数器(占用内存少)。
  • 两种常见的溢出异常,一种OutOfMemoryError(OOM),一种StackOverflowError。

各区溢出情况

  • 堆溢出,当我们创建的对象占用的内存超过最大堆容量时候,会抛出OOM
  • 本地方法栈和虚拟机栈溢出:当请求的栈深度超过虚拟机所允许的深度的时候会抛出栈溢出,这种情况我们在使用递归出错的时候经常遇到;还有就是出现OOM的情况,我们知道分配给这两个栈的内存是有限,和线程数和线程的栈内存有关系,那么当我们其中任意一个过大的话,都有可能造成OOM
  • 方法区和运行时常量池溢出:方法区存放类的信息,有时我们用的框架在动态代理的时候会动态生成CLASS,有时候有很多jsp的时候,这个时候有可能会出现方法区的OOM;而常量池溢出我们可以用String的intern方法(如果常量池没有与字符串相等的字符串,就将这个字符串存入方法区,注意在不同的版本是不同的,1.6之前会将字符串实例复制到永久代,而1.7的没有复制实例,只是在常量池记录首次出现的实例引用)进行模拟。

设置各区的jvm参数

  • 设置堆的最小值-Xms,堆的最大值-Xmx
  • 设置永久代(jdk8之前用永久代来实现方法区)的最小值-XX:PermSize ,最大值-XX:MaxPermSize
  • 设置栈容量-Xss

延伸

关于创建字符串

        String s2=new String("jiajun");
String s6=new String("jiajun");
System.out.println(s2==s6);
  • 结果为false,都存放在堆内存,但是两个地方。
        String s6=new String("jiajun");
String s1="jiajun";
System.out.println(s1==s6);
  • 结果为false,s6存放在堆当中,而s1存放在常量池当中
        String s1="jiajun";
String s7="jiajun";
System.out.println(s1==s7);
  • 结果为true,都是存放在常量池
        String s4="jia";
String s5=s4+"jun";
String s1="jiajun"; System.out.println(s1==s5);
  • 结果为false,变量的值在运行的时候才确定,所以此时s5实际上是new一个对象
        String s3="jia"+"jun";
String s1="jiajun";
System.out.println(s1==s3);
  • 结果为true,此时s1 s3都是指向常量池一个string
        String s1="jiajun";
String s8=new String("jia")+"jun";
System.out.println(s1==s8);
  • 结果为false,此时s8同样是new出来一个对象

我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)

作者:jiajun 出处: http://www.cnblogs.com/-new/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。

初始jvm(一)---jvm内存区域与溢出的更多相关文章

  1. jvm系列 (一) ---jvm内存区域与溢出

    jvm内存区域与溢出 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 为什么学习jvm 木板原理,最短的一块板决定一个水的深度,当一个系统垃圾收集成为瓶颈的时 ...

  2. JVM之Java内存区域

    JVM之Java内存区域 世界上并没有完美的程序,但我们并不因此而沮丧,因为写程序本来就是一个不断追求完美的过程. 一.JAVA内存区域 谈及JAVA虚拟机运行时数据区域就不得不祭出这张经典的图了: ...

  3. JVM中有哪些内存区域,分别是用来干什么的

    前言 之前我们探讨过一个.class文件是如何被加载到jvm中的.但是jvm内又是如何划分内存的呢?这个内被加载到了那一块内存中?jvm内存划分也是面试当中必被问到的一个面试题. 什么是jvm内存区域 ...

  4. JVM:Java内存区域与内存溢出异常

    Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁时间,有些区域随着虚拟机进程的启动而存在,有些区域依赖用户线程的启动和 ...

  5. 史上最详细JVM,Java内存区域讲解

    本人免费整理了Java高级资料,一共30G,需要自己领取:传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 运行时数据区域 JVM载执行Jav ...

  6. JVM总结之内存区域

    Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,有的区域是线程共享的,有的区域是线程隔离的.如下图: 程序计数器 程序计数器(Progra ...

  7. 深入理解JVM - 1 - Java内存区域划分

    作者:梦工厂链接:https://www.jianshu.com/p/7ebbe102c1ae来源:简书简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处. Java与C++之间有一堵 ...

  8. JVM运行时内存区域

    JVM运行java程序时会将内存划分为若干个不同的数据区域: (1)程序计数器: 1.占用内存空间不大. 2.程序计数器相当于JVM所执行的字节码(jvm指令)的“行号指示器”,通过程序计数器的“值” ...

  9. 说说JVM原理?内存泄漏与溢出的区别?何时产生内存泄漏?

    1.JVM原理 JVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个java实现跨平台的最核心的部分,所有的Java程序会首先被编译为.class的类文件,这种类文件可以 ...

随机推荐

  1. Python的核心数据结构

    数据结构 例子 数字 1234,3.1415,3+4j 字符串 'spam'."grace's" 列表 [1,[2,'three'],4] 字典 {'food':'spam','t ...

  2. js中运动框架的封装

    //获取非行间样式的封装 function setStyle(obj,name){ // 考虑兼容性问题 if(obj.currentStyle){//不兼容火狐和谷歌 return obj.curr ...

  3. vue init webpack-simple project 报错处理(connect ETIMEDOUT 192.30.253.112)

    Failed to download repo vuejs-templates/webpack-simple: connect ETIMEDOUT 192.30.253.113:443 Failed ...

  4. 如何使用 ui-router-extras

    为了使用ui-router创建tabs构架,使用ui-router-extras 使用方法: 0. 安装包 bower install ui-router-extras --save-dev 1. 引 ...

  5. mysql+keepalived 双主热备高可用

    理论介绍:我们通常说的双机热备是指两台机器都在运行,但并不是两台机器都同时在提供服务.当提供服务的一台出现故障的时候,另外一台会马上自动接管并且提供服务,而且切换的时间非常短.MySQL双主复制,即互 ...

  6. AVAudioFoundation(2):音视频播放

    本文转自:AVAudioFoundation(2):音视频播放 | www.samirchen.com 本文主要内容来自 AVFoundation Programming Guide. 要播放 AVA ...

  7. JavaScript练习笔记整理·3 - 6.25

    欢迎和大家一起来讨论~   基础练习(1):   我的解答为: function array_diff(a, b) { if (b == "") return a; return ...

  8. Java内存分配及垃圾回收机制(未完待待续)

    Java内存区域 1.内存区域 jvm运行时数据区域 程序计数器 Java虚拟机栈 本地方法栈 方法区 Java堆 大图 2.概念解释 程序计数器   线程私有的一块很小的内存空间,它是当前线程所执行 ...

  9. Spring MVC使用样例

    Spring MVC使用样例 步骤1:添加Spring的相关依赖 1 <dependency> 2 3 <groupId>com.alibaba.external</gr ...

  10. Java面试常考------------------------垃圾收集算法

    对于Java系学生而言,Java虚拟机中的垃圾收集算法是一个很重要的面试考点. 常用的垃圾收集算法主要可划分为以下三类: 1. 标记-清除算法 标记清除算法是一种比较简单的方法,直接标记内存中待回收的 ...