前言

数据库是大家会普遍重视的一个领域,异步通信一般用不到,虚拟机在大部分时候不会出问题,常被人忽视,所以我打算先学习虚拟机,从零单排Java高性能问题。

堆内存存储结构

Java6是以年代来规划内存的,而Java7的G1收集器则相反,这里以Java6为准。

Survivor1和Survivor2是一样大的,必有一个始终为空,容量小于Eden。

垃圾回收机制

年轻代采用复制算法,当回收时,将Eden和Survivor中还存活的对象一次性地复制到另外一块Survivor上,然后清理掉Eden和刚才用过的Survivor空间。每进行一次Minor GC(年轻代回收),对象的年龄就增加1岁(初始为0),当年龄增加到一定程度(默认15岁),就会被移到老年代。老年代的回收算法因篇幅有限在此略过。

从《深入理解Java虚拟机》第二版93页上抄一个例子来做个示范:

package com.jiuyan.mountain.jvm;

public class Test {

  private static final int MB = 1024 * 1024;

  public static void main(String[] args) {
    byte[] bytes1, bytes2, bytes3, bytes4;
    bytes1 = new byte[2 * MB];
    bytes2 = new byte[2 * MB];
    bytes3 = new byte[2 * MB];
    bytes4 = new byte[4 * MB];
  }
}

命令行执行:

java -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 com/jiuyan/mountain/jvm/Test

参数解释:

  1. Xms20M:初始堆20M
  2. Xmx20M:最大堆20M
  3. Xmn10M:年轻代10M
  4. -XX:+PrintGCDetails:打印GC详细信息
  5. -XX:SurvivorRatio=8:Eden和一个Survivor的空间比例是8:1。

输出:

Heap
 PSYoungGen      total 9216K, used 6799K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 8192K, 83% used [0x00000000ff600000,0x00000000ffca3f28,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
  to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
 ParOldGen       total 10240K, used 4096K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  object space 10240K, 40% used [0x00000000fec00000,0x00000000ff000010,0x00000000ff600000)
 PSPermGen       total 21504K, used 2751K [0x00000000f4600000, 0x00000000f5b00000, 0x00000000fec00000)
  object space 21504K, 12% used [0x00000000f4600000,0x00000000f48afc08,0x00000000f5b00000)

JVM没有进行垃圾回收,byte1、byte2、byte3、byte4总共10M内存,而年轻代只有9M内存,不应该啊。结果Eden有6M内存(bytes1,bytes2,bytes3),老年代有4M内存(bytes4),说明bytes4直接被分配到了老年代,因为在Survivor空间中当相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代。

那么我就调用System.gc()来主动触发一次GC。

输出:

[GC-- [PSYoungGen: 6635K->6635K(9216K)] 10731K->14827K(19456K), 0.0035280 secs] [Times: user=0.00 sys=0.01, real=0.00 secs]
[Full GC [PSYoungGen: 6635K->2275K(9216K)] [ParOldGen: 8192K->8192K(10240K)] 14827K->10467K(19456K) [PSPermGen: 2743K->2742K(21504K)], 0.0079080 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
Heap
 PSYoungGen      total 9216K, used 2441K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 8192K, 29% used [0x00000000ff600000,0x00000000ff8624d8,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
  to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
 ParOldGen       total 10240K, used 8192K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  object space 10240K, 80% used [0x00000000fec00000,0x00000000ff400030,0x00000000ff600000)
 PSPermGen       total 21504K, used 2750K [0x00000000f4600000, 0x00000000f5b00000, 0x00000000fec00000)
  object space 21504K, 12% used [0x00000000f4600000,0x00000000f48af8d0,0x00000000f5b00000)

日志分析:

  • GC和Full GC说明了这次垃圾收集的停顿类型,而不是用来区分年轻代还是老年代的。如果有“Full”,说明这次GC发生了STW(Stop-The-World)。
  • PSYoungGen是采用Parallel Scavenge收集器的年轻代,ParOldGen是采用Parallel Old收集器的老年代,Tenured是采用Serial Old收集器的老年代。
  • [PSYoungGen: 6635K->6635K(9216K)]表示GC前年轻代占用内存6M,GC后占用内存6M,内存区域总容量9M。10731K->14827K(19456K)表示GC前堆占用内存10M,GC后占用内存14M,堆总容量20M。
  • GC过程是把年轻代中的4M内存复制到了老年代,所以才会出现10731K->14827K(19456K),Full GC过程是把年轻代中的4M内存回收掉,所以才会出现PSYoungGen: 6635K->2275K(9216K)。

JVM垃圾回收机制入门的更多相关文章

  1. JVM垃圾回收机制总结:调优方法

    转载: JVM垃圾回收机制总结:调优方法 JVM 优化经验总结 JVM 垃圾回收器工作原理及使用实例介绍

  2. JVM内存管理和JVM垃圾回收机制

    JVM内存管理和JVM垃圾回收机制(1) 这里向大家描述一下JVM学习笔记之JVM内存管理和JVM垃圾回收的概念,JVM内存结构由堆.栈.本地方法栈.方法区等部分组成,另外JVM分别对新生代和旧生代采 ...

  3. JVM垃圾回收机制概述

    JVM垃圾回收机制概述 1.定义 是指JVM用于释放那些不再使用的对象所占用的内存. 2.方式 2.1引用计数(早期) 当引用程序创建引用以及引用超出范围时,JVM必须适当增减引用数.当某个对象的引用 ...

  4. Java虚拟机学习笔记——JVM垃圾回收机制

    Java虚拟机学习笔记——JVM垃圾回收机制 Java垃圾回收基于虚拟机的自动内存管理机制,我们不需要为每一个对象进行释放内存,不容易发生内存泄漏和内存溢出问题. 但是自动内存管理机制不是万能药,我们 ...

  5. JVM基础系列第8讲:JVM 垃圾回收机制

    在第 6 讲中我们说到 Java 虚拟机的内存结构,提到了这部分的规范其实是由<Java 虚拟机规范>指定的,每个 Java 虚拟机可能都有不同的实现.其实涉及到 Java 虚拟机的内存, ...

  6. JVM内存管理、JVM垃圾回收机制、新生代、老年代以及永久代

    内存模型 JVM运行时数据区由程序计数器.堆.虚拟机栈.本地方法栈.方法区部分组成,结构图如下所示. JVM内存结构由程序计数器.堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 1)程序计数器 ...

  7. JVM 垃圾回收机制和常见算法和 JVM 的内存结构和内存分配(面试题)

    一.JVM 垃圾回收机制和常见算法 Sun 公司只定义了垃圾回收机制规则而不局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同.GC(Garbage Collector)在回收对象前首先必 ...

  8. JVM垃圾回收机制和常用算法

    由于疫情的原因,所以目前一直在家远程办公,所以很多时间在刷面试题,发现2019大厂的面试虽然种类很多,但是总结了一下发现主要是这几点:算法和数据结构. JVM.集合.多线程.数据库这几点在面试的时候比 ...

  9. 真的可惜,四面阿里,结果我被JVM垃圾回收机制与 OOM异常卡住了

    前言 为什么需要垃圾回收 首先我们来聊聊为什么会需要垃圾回收,假设我们不进行垃圾回收会造成什么后果,我们举一个简单的例子 我们住在一个房子里面,我们每天都在里面生活,然后垃圾都丢在房子里面,又不打扫, ...

随机推荐

  1. iOS6以后的单个控制器横竖屏显示以及旋转屏控制技巧,附带iOS8以后显示电池状态栏

    一.在应用中从竖屏模式强制转换为横屏模式 第一种方法:通过模态弹出视图的方式,使得特定ViewController坚持特定的interfaceOrientation(1)iOS6之后提供了这样一个方法 ...

  2. BFC块级格式化上下文简述

    做过页面编写的各位应该对定位不陌生了,这个样式表中的重头戏,也是最难把控的元素之一,今天在这里我们要讲到的就是与浮动与清除浮动相关的定位元素,对于定位有很多种,有绝对定位,还有相对定位,固定定位,静态 ...

  3. yum安装ftp服务器

    1.安装vsftp,本文采用yum安装: #yum install vsftpd 2.安装后运行: # service vsftpd restart Shutting downvsftpd:      ...

  4. Java学习----一个对象怎么调用另一个对象呢?

    打包 jar cvfm test1.jar manifmest.mf teacher.class student.class test1.class 运行 java -jar test1.jar pu ...

  5. pkg-config相关的常用指令

    pkg-config用途: 查询系统已安装库的基础信息(元信息) 1.查看所有的pkg-config库 pkg-config --list-all --list-all  列出pkg-config路径 ...

  6. 【C语言】结构组成(函数、语句、注释)

    C语言结构组成 一.相关基础知识 二.具体内容 C语言由函数.语句和注释三部分组成: )函数与主函数:     一个C语言源程序可以由一个或多个源文件组成,每个源文件可由一个或多个函数组成,一个源程序 ...

  7. SOA和微服务

    SOA和微服务 SOA和微服务到底是什么关系? 说实话,我确实不明白SOA和微服务到底有什么本质上的区别,两者说到底都是对外提供接口的一种架构设计方式.我倒觉得微服务其实就是随着互联网的发展,复杂的平 ...

  8. 解决Maven中Missing artifact javax.jms:jms:jar:1.1:compile

    搭建好项目后报错: Missing artifact javax.jms:jms:jar:1.1:compile  于POM.xml中 解决方案: 一 :在nexus中配置一个代理仓库     地址为 ...

  9. OC 之 谓词

    NSPredicate 分类: Objective-C iOS XCode Mac2012-10-26 17:26 10557人阅读 评论(1) 收藏 举报 简述:Cocoa框架中的NSPredica ...

  10. 优秀开源项目的svn地址

    很多优秀的开源项目已经提供SVN源码签出了,无论是解疑还是学习,都是一大幸福之事啊! Apache的SVN库,强烈推荐! http://svn.apache.org/repos/asf/ 里面不但有S ...