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系列1:内存区域

    1.JVM运行区域内存划分 2.各内存区域详细介绍 2.1 程序计数器 程序计数器是一块很小的内存区域,它作为前线程所执行的字节码的行号指示器,指向当前class文件的执行代码的行数.字节码解释器工作 ...

  2. 初始jvm(一)---jvm内存区域与溢出

    jvm内存区域与溢出 为什么学习jvm 木板原理,最短的一块板决定一个水的深度,当一个系统垃圾收集成为瓶颈的时候,那么就需要你对jvm的了解掌握. 当一个系统出现内存溢出,内存泄露的时候,因为你懂jv ...

  3. JVM性能优化系列-(1) Java内存区域

    1. Java内存区域 1.1 运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.主要包括:程序计数器.虚拟机栈.本地方法栈.Java堆.方法区(运 ...

  4. JVM探秘:Java内存区域

    本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. 概述 Java 虚拟机为程序员分担了很多内存管理的工作,不再像 C/C++ 那样容易出 ...

  5. jvm系列(七):jvm调优-工具篇

    16年的时候花了一些时间整理了一些关于jvm的介绍文章,到现在回顾起来还是一些还没有补充全面,其中就包括如何利用工具来监控调优前后的性能变化.工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗 ...

  6. jvm系列(八):jvm知识点总览-高级Java工程师面试必备

    在江湖中要练就绝世武功必须内外兼备,精妙的招式和深厚的内功,武功的基础是内功.对于武功低(就像江南七怪)的人,招式更重要,因为他们不能靠内功直接去伤人,只能靠招式,利刃上优势来取胜了,但是练到高手之后 ...

  7. jvm系列(四):jvm知识点总结

    原文链接:http://www.cnblogs.com/ityouknow/p/6482464.html jvm 总体梳理 jvm体系总体分四大块: 类的加载机制 jvm内存结构 GC算法 垃圾回收 ...

  8. jvm系列(八):jvm知识点总览

    在江湖中要练就绝世武功必须内外兼备,精妙的招式和深厚的内功,武功的基础是内功.对于武功低(就像江南七怪)的人,招式更重要,因为他们不能靠内功直接去伤人,只能靠招式,利刃上优势来取胜了,但是练到高手之后 ...

  9. JVM系列五:JVM监测&工具

    JVM系列五:JVM监测&工具[整理中]  http://www.cnblogs.com/redcreen/archive/2011/05/09/2040977.html 前几篇篇文章介绍了介 ...

随机推荐

  1. Tomcat 配置学习

    1 server.xml <host appBase="d:/aaa"> <Context path="/smswap" reloadable ...

  2. TITLE: BizTalk Server 2013 Administration Console

    TITLE: BizTalk Server 2013 Administration Console------------------------------ Could not store tran ...

  3. mysql分页(ajax)

    分页有多种方式,mysql的limit是个不错的选择,通过ajax实现异步刷新,将当前页数和每页数量传入后台即可 1. 首先后台要拿到总记录数和所需显示数据列表,所以要分别写两个sql方法 我这里是通 ...

  4. BZOJ3747:[POI2015]Kinoman(线段树)

    Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l< ...

  5. 【转】合格PHP工程师的知识结构

    PHP的运行环境 连环境都搞不起来,就是你有多么喜欢PHP,那也是白搭,开始我们大多会使用集成环境软件例如xampp,wamp.随着知识的增加慢慢要学会自己搭建运行环境,例如 Linux(Ubuntu ...

  6. Hive学习之路 (七)Hive的DDL操作

    库操作 1.创建库 语法结构 CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name [COMMENT database_comment] //关 ...

  7. PAT乙级1033

    1033 旧键盘打字 (20 分)   旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及坏掉的那些键,打出的结果文字会是怎样? 输入格式: 输入在 2 ...

  8. P1353 [USACO08JAN]跑步Running

    题目描述 The cows are trying to become better athletes, so Bessie is running on a track for exactly N (1 ...

  9. 在ubuntu中添加widows启动项的简单方法

    打开终端执行: sudo vim /boot/grub/grub.cfg 或者 sudo gedit /boot/grub/grub.cfg 打开文件grub.cfg. 在文件中添加:添加的时候注意和 ...

  10. Stm32-uclinux启动后的调试

    Stm32-uclinux启动后的调试 1.  修改__pfn_to_page使得能够启动 根据STM32F103 ucLinux开发之三(内核启动后不正常)的描述,内核无法启动是选择了平板内存模式后 ...