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. 多校hdu5754(博弈)

    ©此题中在N×M的棋盘中从(1,1)走到(N,M)B先走G后走,谁先到(N,M)谁赢,走法分为4中分别是国际象棋中的国王,车,马,王后的发,在四种走法下谁能赢: 我们依次分析每一种棋子. ①王. 首先 ...

  2. 元素 "context:component-scan" 的前缀 "context" 未绑定的解决方案

    在动态web项目(Dynamic Web Project)中,使用SpringMVC框架,新建Spring的配置文件springmvc.xml,添加扫描控制器 <context:componen ...

  3. Spark常用算子-KeyValue数据类型的算子

    package com.test; import java.util.ArrayList; import java.util.List; import java.util.Map; import or ...

  4. Codeforces Round #425 (Div. 2) D 树链剖分 + 树状数组维护区间

    一看就知道 可以LCA判断做 也可以树链剖分拿头暴力 然而快速读入和线段树维护区间会T70 于是只能LCA? 线段树的常数不小 于是需要另外一种办法来进行区间加减和查询区间和 就是使用树状数组 这个题 ...

  5. Java 通过JDBC连接Mysql数据库的方法和实例【图文说明】

    JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口 ...

  6. JMeter 3.0 POST Body Data 中文乱码问题

    现象如下图所示:

  7. review32

    一个类的两个对象如果具有相同的引用,那么他们就具有相同的实体和功能.

  8. 为mac终端添加tree命令

    原文:http://superuser.com/questions/359723/mac-os-x-equivalent-of-the-ubuntu-tree-command/ 整理步骤如下: $ t ...

  9. MySQL InnoDB与MyISAM存储引擎差异

    言: 之前简单介绍过 MySQL 常用的存储引擎,今天对两个主流的存储简单分析下差异,书上没有参考的笔试题解答注解: 差异: MyISAM 只支持表锁,不支持事务,表损坏率较高.较老的存储引擎.   ...

  10. java 文件类 null与exists()是不一样的

    java 文件类 null与exists()是不一样的File imageFile0A=null; (imageFile0A==null)与!imageFile0A.exists() 不等价! 一个文 ...