JVM内存详解-阅读笔记
JVM内存详解
1 本机内存介绍
1.1 硬件限制
1.2 操作系统和虚拟内存
1.2.1 虚拟内存可增加可用内存空间, 但是可能引起性能问题
1.2.2 内核空间和用户空间
2 内存耗尽时现象
当Java 堆耗尽时,Java 应用程序很难正常运行,因为Java 应用程序必须通过分配对象来完成工作。只要Java 堆被填满,就会出现糟糕的GC 性能并抛出表示Java 堆被填满的OutOfMemoryError。
相反,一旦Java运行时开始运行并且应用程序处于稳定状态,它可以在本机堆完全耗尽之后继续正常运行。不一定会发生奇怪的行为,因为需要分配本机内存的操作比需要分配Java 堆的操作少得多。但一些常见操作还是会报错:启动线程、加载类以及执行某种类型的网络和文件I/O。
3 如何占用本机内存
3.1 java堆
Java 堆是分配了对象的内存区域。
堆的大小可以在Java 命令行使用 -Xmx 和 -Xms 选项来控制(mx 表示堆的最大大小,ms 表示初始大小)。
Java堆占用的本机内存为-Xmx,未被使用的部分为保留内存,保留内存不会分配给其他程序使用;
对于维护Java 堆的内存管理系统,需要更多本机内存来维护它的状态。例如行垃圾收集。
3.2 垃圾收集
3.3 即时(JIT)编译
JIT 编译器在运行时编译Java 字节码来优化本机可执行代码。这极大地提高了Java 运行时的速度,并且支持Java 应用程序以与本机代码相当的速度运行。
但JIT 编译器的输入(字节码)和输出(可执行代码)必须也存储在本机内存中。
3.4 类和类加载器
存储类的方式取决于具体实现。Sun JDK 使用永久生成(permanent generation,PermGen)堆区域。Java 5 的IBM 实现会为每个类加载器分配本机内存块,并将类数据存储在其中。
从最基本的层面来看,使用更多的类将需要使用更多内存。
Java运行时可以卸载类来回收空间,但是只有在非常严酷的条件下才会这样做。不能卸载单个类,而是卸载类加载器,随其加载的所有类都会被卸载。只有在以下情况下才能卸载类加载器:
Java 堆不包含对表示该类加载器的 java.lang.ClassLoader 对象的引用。
Java 堆不包含对表示类加载器加载的类的任何 java.lang.Class 对象的引用。
在Java 堆上,该类加载器加载的任何类的所有对象都不再存活(被引用)。
需要注意的是,Java 运行时为所有Java 应用程序创建的3 个默认类加载器(bootstrap、extension 和 application )都不可能满足这些条件,因此,任何系统类(比如 java.lang.String)或通过应用程序类加载器加载的任何应用程序类都不能在运行时释放。
3.5 JNI
JNI 应用程序可能通过3 种方式增加Java 运行时的本机内存占用:
JNI 应用程序的本机代码被编译到共享库中,或编译为加载到进程地址空间中的可执行文件。大型本机应用程序可能仅仅加载就会占用大量进程地址空间。
本机代码必须与Java 运行时共享地址空间。任何本机代码分配或本机代码执行的内存映射都会耗用Java 运行时的内存。
某些JNI 函数可能在它们的常规操作中使用本机内存。GetTypeArrayElements 和GetTypeArrayRegion 函数可以将Java堆数据复制到本机内存缓冲区中,以供本机代码使用。是否复制数据依赖于运行时实现。(IBM Developer Kit for Java 5.0 和更高版本会进行本机复制)。
通过这种方式访问大量Java 堆数据可能会使用大量本机堆
3.6 NIO
直接bytebuffer会操作本机内存;
3.7 线程
线程的堆栈空间、线程本地存储(thread-local storage)和内部数据结构会占用本机内存。
堆栈大小因Java 实现和架构的不同而不同。一些实现支持为Java 线程指定堆栈大小,其范围通常在256KB 到756KB 之间。
4 调试方法和技术
4.1 检查java堆
JavaCore文件、heapdump文件;
4.2 检查本机堆
Windows 提供的PerfMon 工具;
Linux 使用命令行工具(比如 ps、top 和 pmap)能够显示应用程序的本机内存占用情况。配合使用GCMV,进行长时间跟踪后的分析。
由于JVM 前期阶段的本机内存增长而耗尽本机内存,以及内存使用随负载增加而增加,这些都是尝试在可用空间中做太多事情的例子。在这些场景中,您的选择是:
减少本机内存使用。缩小Java 堆大小是一个好的开端。
限制本机内存使用。如果您的本机内存随负载增加而增加,可以采取某种方式限制负载或为负载分配的资源。
增加可用地址空间。这可以通过以下方式实现:调优您的操作系统(例如,在Windows 上使用/3GB 开关增加用户空间,或者在Linux 上使用庞大的内核空间),更换平台(Linux 通常拥有比Windows 更多的用户空间),或者 转移到64 位操作系统。
4.3 是什么在使用本机内存
根据您的Java 设置,将会使用多少本机内存。根据以下指南粗略估算一下:
Java 堆占用的内存至少为-Xmx 值。
每个Java 线程需要堆栈空间。堆栈空间因实现不同而异,但是如果使用默认设置,每个线程至多会占用756KB 本机内存。
直接 ByteBuffer 至少会占用提供给allocate() 例程的内存值。
UMDH 支持就地 调试Windows 上本机内存泄漏,在Linux 上,您可能需要进行一些传统的调试,而不是依赖工具来解决问题。下面是一些建议的调试步骤:
提取测试案例。生成一个独立环境,您需要能够在该环境中再现本机内存泄漏。这将使调试更加简单。
尽可能缩小测试案例。尝试禁用函数来确定是哪些代码路径导致了本机内存泄漏。如果您拥有自己的JNI 库,可以尝试一次禁用一个来确定是哪个库导致了内存泄漏。
缩小Java 堆大小。Java 堆可能是进程的虚拟地址空间的最大使用者。通过减小Java 堆,可以将更多空间提供给本机内存的其他使用者。
关联本机进程大小。一旦您获得了本机内存随时间的使用情况,可以将其与应用程序工作负载和GC 数据比较。如果泄漏程度与负载级别成正比,则意味着泄漏是由每个事务或操作路径上的某个实体引起的。如果当进行垃圾收集时,本机进程大小显著减小,这意味着您没遇到内存泄漏,您拥有的是具有本机支持的对象组合(比如直接 ByteBuffer)。通过缩小Java 堆大小(从而迫使垃圾收集更频繁地发生),或者在一个对象缓存中管理对象(而不是依赖于垃圾收集器来清理对象),您可以减少本机支持对象持有的内存量。
5 消除限制
更改为64位,但是64位可能引入对象膨胀的问题;
必须关注物理内存是否满足Java程序使用,一旦物理内存不足,发生频繁的与虚拟内存交换,会严重影响性能。
JVM内存详解-阅读笔记的更多相关文章
- Java中堆内存和栈内存详解2
Java中堆内存和栈内存详解 Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...
- NGINX高性能Web服务器详解(读书笔记)
原文地址:NGINX高性能Web服务器详解(读书笔记) 作者:夏寥寥 第4章 Nginx服务器的高级配置 4.1 针对IPv4的内核7个参数的配置优化 说明:我们可以将这些内核参数的值追加到Linu ...
- 孙鑫视频VC++深入详解学习笔记
孙鑫视频VC++深入详解学习笔记 VC++深入详解学习笔记 Lesson1: Windows程序运行原理及程序编写流程 Lesson2: 掌握C++基本语法 Lesson3: MFC框架程序剖析 Le ...
- DDR3内存详解,存储器结构+时序+初始化过程
DDR3内存详解,存储器结构+时序+初始化过程 标签: DDR3存储器博客 2017-06-17 16:10 1943人阅读 评论(1) 收藏 举报 分类: 硬件开发基础(2) 转自:http:/ ...
- NAND_FLASH_内存详解与读写寻址方式
一.内存详解 NAND闪存阵列分为一系列128kB的区块(block),这些区块是 NAND器件中最小的可擦除实体.擦除一个区块就是把所有的位(bit)设置为"1"(而所有字节(b ...
- JVM结构详解
JVM 结构详解 JVM 结构图 程序计数器(PC 寄存器) 程序计数器的定义 程序计数器是一块较小的内存空间,是当前线程正在执行的那条字节码指令的地址.若当前线程正在执行的是一个本地方法,那么此时程 ...
- TCP/IP详解学习笔记
TCP/IP详解学习笔记(1)-基本概念 TCP/IP详解学习笔记(2)-数据链路层 TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议 TCP/IP详解学习笔记(4)-ICMP协议, ...
- [转]JVM指令详解(上)
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 本文主要记录一些JVM指令,便于记忆与查阅. 一.未归类系列A 此系列暂未归类. 指令码 助记符 ...
- TCP/IP详解学习笔记 这位仁兄写得太好了
TCP/IP详解学习笔记(1)-基本概念 为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣 ...
随机推荐
- Android开发学习之路--Android Studio项目目录结构简介
既然已经搭建好环境了,那就对Android Studio中项目目录结构做个简单的了解了,这里以最简单的Hello工程为例子,新建好工程后看如下三个工程视图: 1.Android工程 manifests ...
- 编译GDAL使用最新的HDF库配置文件
HDF库最新版本中的动态库以及目录结构都发生了变化,导致按照之前的博客进行编译GDAL时,会出问题.使用HDF4版本为HDF4-4.2.10,HDF5的版本为HDF5-1.8.12.两个库的目录结构如 ...
- Android Handler机制剖析
android的handler机制是android的线程通信的核心机制 Android UI是线程不安全的,如果在子线程中尝试进行UI操作,程序就有可能会崩溃. Android中的实现了 接收消息的& ...
- ubuntu文件管理常用命令
1.关闭防火墙:ufw disable 2.以.开头的表示隐藏文件 3..和..分别代表当前目录以及当前目录的父目录 4.显示当前用户所在目录pwd 5.touch创建空文件 6.mkdir创建新目录 ...
- OpenCV计算物体的重心坐标(2值图像)
效果图: 代码: // FindGravity.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream& ...
- 1021. Deepest Root (25) -并查集判树 -BFS求深度
题目如下: A graph which is connected and acyclic can be considered a tree. The height of the tree depend ...
- 使用dom4j技术对xml文档进行增删改练习(一)
整个流程如下面代码所以,并对一些重要代码意义做出详细解释: import java.io.File; import java.io.FileOutputStream; import org.dom4j ...
- Linux 之归档与压缩
首先我们思考一下,归档和解压是一个概念吗?答案很明显不是啊,所谓归档,就是将一些文件归到一起,并没有对其进行压缩的操作.然而压缩则不同,见名知意.下面我们就来深入的研究一下这两个知识点吧! ----- ...
- STL - set和multiset
set/multiset的简介 set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列.元素插入过程是按排序规则插入,所以不能指定插入位置. set采用红黑树变体的数据结构实现, ...
- Web service request SetParameters to Report Server http://host/reportserver failed. Error: 请求因 HTTP 状态 401 失败: Unauthorized
迁移CRM服务器完成后在访问CRM的内部报表时报错,在查看应用服务器的日志时发现报"Web service request SetParameters to Report Server ht ...