JVM内存结构

Heap Space:

堆内存(Heap Space)是由Young Generation和Old Generation组成,而Young Generation又被分成三部分,Eden,From Survivor和To Survivor默认比例为8:1:1

堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,大部分对象实例都在这里分配内存

堆是垃圾收集管理的主要区域,如果在堆内存耗尽,并且无法再扩展时,将会抛出OutOfMemoryError异常。

Method Area:

又称为非堆内存。在HotSpot虚拟机上属于Permanent Generation。

方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,是线程共享的区域。

栈又分为java虚拟机栈和本地方法栈主要用于方法的执行。

这个区域的内存回收主要是针对常量池的回收和对类的卸载,一般不发生。

根据Java虚拟机规范的规定,当方法区耗尽时,将抛出OutOfMemoryError异常。 

Native Area:

Native方法区,包含PC,栈及C/C++运行环境。

PC(Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。

JVM Stacks是线程私有的,它的生命周期与线程相同。虚拟机栈是Java方法执行的内存:每个方法被执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。

局部变量表存放了编译期可知的各种基本数据类型、对象引用和Return Address。栈帧所需的内存空间在编译期间完成分配,运行期间不会改变局部变量表的大小。

JVM规范中规定了栈的两种异常状况:

1.如果栈的深度大于所允许的深度,将抛出StackOverflowError异常,如死递归;

2.如果内存耗尽,则抛出OutOfMemoryError异常。

Native Method Stacks与JVM Stack类似,是保存Native方法栈。

内存调优:

jvm参数:-Xms, -Xmx ,-Xmn ,-XX:SurvivorRatio,-XX:MaxTenuringThreshold,-XX:PermSize,-XX:MaxPermSize

-Xms -Xmx ,为避免运行时JVM不断调整堆内存大小,通常设置为相同的值,该值决定了JVM heap所能使用的最大内存

-XX:PermSize、-XX:MaxPermSize 用来控制非堆内存的大小,通常设置为相同的值

-Xss  每个线程的栈大小

-Xmn 决定了YG的大小,Eden、FS、TS三个区域的比例可以通过-XX:SurvivorRatio来控制,默认为8:1:1

-XX:MaxTenuringThreshold 设置对象在经过多少次minor GC之后进入老年代,此参数只有在Serial 串行GC时有效

1.新生代设置调小,会使minorGC次数增加,对象年龄增长变快,使其提前进入老年代,老年代内存增长,会触发FullGC

2.新生代设置过大,会导致老年代变小,当其内存耗尽,会触发FullGC

监测工具(JDK自带):

jconsole

图形界面及命令行的java性能分析工具

http://docs.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html

jvisualvm 

jconsole的升级版

jinfo  

可获取详细的java配置信息

格式: jinfo pid

jmap

可监测运行中的jvm物理内存的占用情况

如:jmap -heap pid  打印heap信息

jmap -dump:format=b,file=heap.hprof pid   输出dump文件

jmap -h 查看帮助

jstack

监测jvm中当前所有线程的运行情况和线程当前状态

jstat 

可利用了JVM内建的指令对Java程序的资源和性能进行实时的命令行的监控,包括各种堆和非堆的大小及其内存使用量、classloader、compiler、垃圾回收状况等。

格式:jstat -option -t -h pid interval count

如: jstat -printcompilation -h15 pid 500 500

参数说明

-h15 每隔15行打印一次标题

interval  每隔500ms打印一次

count  共打印500次

options:

class     统计class loader行为信息
compiler   统计编译行为信息
gc       统计jdk gc时heap信息
gccapacity     统计堆内存不同代的heap容量信息
gccause   统计gc的情况(同-gcutil)和引起gc的事件
gcnew     统计gc时新生代的信息(相比gcutil更详细)
gcnewcapacity   统计gc时新生代heap容量
gcold   统计gc时,老年区的情况
gcoldcapacity   统计gc时,老年区heap容量
gcpermcapacity   统计gc时,permanent区heap容量
gcutil     统计gc时,heap情况
printcompilation   统计编译行为信息

测试堆内存溢出:

新建文件MemTest.java,输入代码:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; public class MemTest { public static void main(String[] args) { int count = args.length == 1 ? Integer.parseInt(args[0]) : 30; List<List> list = new LinkedList<List>();
long max = Runtime.getRuntime().maxMemory();
long totle = Runtime.getRuntime().totalMemory(); int i = 0;
while (true) {
list.add(new ArrayList<Integer>(1024)); if (i++ > count) {
long free = Runtime.getRuntime().freeMemory();
System.out.println("max:" + max / (1<<20) + "m totle:" + totle/(1<<20) + "m free=" + free/1024 + "kb");
i = 0;
} }
} }

输入:

javac MemTest.java

java -Xms10m -Xmx10m MemTest 50

输出:

end

Java基础--虚拟机JVM的更多相关文章

  1. Java基础篇(JVM)——类加载机制

    这是Java基础篇(JVM)的第二篇文章,紧接着上一篇字节码详解,这篇我们来详解Java的类加载机制,也就是如何把字节码代表的类信息加载进入内存中. 我们知道,不管是根据类新建对象,还是直接使用类变量 ...

  2. Java基础篇(JVM)——字节码详解

    这是Java基础篇(JVM)的第一篇文章,本来想先说说Java类加载机制的,后来想想,JVM的作用是加载编译器编译好的字节码,并解释成机器码,那么首先应该了解字节码,然后再谈加载字节码的类加载机制似乎 ...

  3. Java基础技术JVM面试【笔记】

    Java基础技术JVM面试[笔记] JVM JVM 对 java 类的使用总体上可以分为两部分:一是把静态的 class 文件加载到 JVM 内存,二是在 JVM 内存中进行 Java 类的生命周期管 ...

  4. Java基础-考察JVM内部结构的常用工具介绍

    Java基础-考察JVM内部结构的常用工具介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们可以通过jvisualvm.exe考察jvm内部结构.而jvisualvm.exe ...

  5. Java基础:JVM垃圾回收算法

    众所周知,Java的垃圾回收是不需要程序员去手动操控的,而是由JVM去完成.本文介绍JVM进行垃圾回收的各种算法. 1. 如何确定某个对象是垃圾 1.1. 引用计数法 1.2. 可达性分析 2. 典型 ...

  6. Java基础篇——JVM之GC原理(干货满满)

    原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10697554.html ,多多支持哈! 一.什么是GC? GC是垃圾收集的意思,内存处理是 ...

  7. 面试【JAVA基础】JVM

    1.内存模型 1.1.堆 堆是所有线程共享的,主要存放对象实例和数组. 新生代和老年代的比例是1:2. 新生代中三个区域的比例是 8 : 1 : 1. 1.1.1.新生代 对象分配在eden区中,当e ...

  8. java基础JDK jvm path环境变量

    JDk=JRE +java的开发工具(javac.exe java.exe javadoc.exe)JRE =JVM +Java核心类库 2.为什么 要配置 path环境变量 ?如何配置?JAVA_H ...

  9. Java基础学习-Java语言概述

    一.Java语言发展史 创始人:詹姆斯·高斯林(James Gosling) 公司:SUN——(Stanford University Network斯坦福大学网络公司) 1995年5月23日,Jav ...

随机推荐

  1. c++ boost库学习三:实用工具

    noncopyable 大家都知道定义一个空类的时候,它实际包含了构造函数,拷贝构造函数,赋值操作符和析构函数等. 这样就很容易产生一个问题,就是当用户调用A a(“^_^") 或者A c= ...

  2. hql join

    文章一: 1.用hql语句 ` String hql="select student.id, student.name ,class.name from student映射实体类名 as s ...

  3. MySQLdump导出sql脚本

    1.问题描述 通过图形化工具,在查询窗口用select语句按条件查询出所需结果,然后用“导出向导”把查询结果导成sql文件,但是导出来的sql语句不全,没有表名.字段名. 通过图形化工具,试了好多次都 ...

  4. inline-block和同级的text-align问题

    https://www.cnblogs.com/qjqcs/p/5551640.html margin:0 auto:是设置块标签在父级中居中对齐,是一种对齐方式.所以对于display:inline ...

  5. Nuxt / Vue.js in TypeScript: Object literal may only specify known properties, but 'components' does not exist in type 'VueClass'

    项目背景, Nuxt(vue), TypeScript 生成完项目框架, 添加测试demo页面. 在生成的模板代码中添加layout配置如下: <script lang="ts&quo ...

  6. R语言学习笔记(1)

    第一章:R语言介绍 一 R的使用 1 R是一种区分大小写的解释型语言.R语句由函数和赋值构成.R使用<-作为赋值符号.例如: x<-rnorm(5) 创建了一个名为x的向量对象,它包含5个 ...

  7. rpm卸载软件error preun

    这两天,使用ipvsadm -ln总是显示空. 后来,使用strace ipvsadm -ln定位 看来,是ipvsadm模块有问题,卸载了再重新安装吧,结果出现这种问题. 从来没遇到这种问题: er ...

  8. QT QStringListModel 示例代码

    1.  QStringListModel , 实现 插入 删除 编辑 list,支持鼠标双击编辑. 2. dialog.h #ifndef DIALOG_H #define DIALOG_H #inc ...

  9. Functions should do one thing一个函数应该只做一件事

    if you take nothing else away from this guide other than this, you'll be ahead of many developers. 如 ...

  10. iOS中,Framework和.a的打包及使用

    最近在做一个小项目,需要给客户一个demo测试,有一部分核心代码暂时不想让客户知道,就想到了打包成framework或.a库.库有两种: 静态库:.a和.framework 动态库:.tbd和.fra ...