`
STAR_JAVA
  • 浏览: 2205 次
  • 性别: Icon_minigender_1
  • 来自: 大连
最近访客 更多访客>>
社区版块
存档分类
最新评论

java虚拟机学习笔记1-jvm的逻辑内存分配

    博客分类:
  • JVM
 
阅读更多

java虚拟机学习笔记1-jvm的逻辑内存分配

声明

博客内所有“java虚拟机学习笔记”系列的文章,均出自《深入理解java虚拟机-JVM高级特性与最佳实践-周志明》

 

java虚拟机在执行java程序的过程中把他所管理的内存划分成不同的逻辑数据区域,这些区域各有用途,特点不同,以下是根据《java虚拟机规范(第3版)》中规定的jvm运行时数据区域


 

对于以上各个区域的详细说明,参见附件中的 Java虚拟机规范(Java_SE_7).pdf 

 

下面,进入实战OutOfMemoryError异常

 

1.java堆溢出

 

首先限制java堆的大小为20MB,不可扩展(将Xms,Xmx 的值设置为相同),通过

设置 -XX:+HeapDumpOnOutOfMemoryError 可以使JVM在内存溢出时Dump出内存转储快照以便事后分析

 

 

package org.star_java.jvm.memory;

import java.util.ArrayList;
import java.util.List;

/**
 * VM Args -verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:SurvivorRatio=8
 */
public class HeapOOM
{
	static class OOMObject
	{
		public static void main(String[] args)
		{
			List<OOMObject> list = new ArrayList<OOMObject>();
			while (true)
			{
				list.add(new OOMObject());
			}
		}
	}
}
 

 

运行结果:

 

java.lang.OutOfMemoryError: Java heap space

Dumping heap to java_pid1068.hprof ...

Heap dump file created [27834496 bytes in 0.186 secs]

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

at java.util.Arrays.copyOf(Unknown Source)

at java.util.Arrays.copyOf(Unknown Source)

at java.util.ArrayList.grow(Unknown Source)

at java.util.ArrayList.ensureCapacityInternal(Unknown Source)

at java.util.ArrayList.add(Unknown Source)

at org.star_java.jvm.memory.HeapOOM$OOMObject.main(HeapOOM.java:18)

 

我们可以使用一些工具查看生成的内存转储快照,以下是使用 jvisualvm 查看的结果


可以清晰的看出我们自己定义的类OOMObject造成了此次溢出

 

2.虚拟机栈和本地方法栈溢出

 

在HotSpot虚拟机中不区分虚拟机栈和本地方法栈,所以设置-Xoss(设置本地方法栈大小)是无效的,所以这里使用-Xss(栈容量)参数,关于本例,抛出2个异常:

1.如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverFlowError

2.如果虚拟机在扩展栈的深度时无法请求道足够的内存空间,则抛出OutOfMemoryError

 

 

package org.star_java.jvm.memory;

/**
 *  VM Args -Xss128k
 */
public class JavaVmStackSOF
{
	private int stackLength = 1;
	
	private void stackLeak()
	{
		stackLength++;
		stackLeak();
	}
	
	public static void main(String[] args)
	{
		JavaVmStackSOF oom = new JavaVmStackSOF();
		try
		{
			oom.stackLeak();
		}
		catch (Exception e)
		{
			System.out.println("stack length : " + oom.stackLength);
			throw e;
		}
	}
}
 

运行结果:

stack length : 2242

 

Exception in thread "main" java.lang.StackOverflowError

at org.star_java.jvm.memory.JavaVmStackSOF.stackLeak(JavaVmStackSOF.java:12)

at org.star_java.jvm.memory.JavaVmStackSOF.stackLeak(JavaVmStackSOF.java:13)

at org.star_java.jvm.memory.JavaVmStackSOF.stackLeak(JavaVmStackSOF.java:13)

...................................................................................................................................

...................................................................................................................................

at org.star_java.jvm.memory.JavaVmStackSOF.main(JavaVmStackSOF.java:21)

 

3.方法区溢出

 

方法去用于存放Class的相关信息,本例的基本思路是在运行时产生大量的类去填满方法区,直到溢出。

可以利用java的反射模拟本例,但是此处使用原作者的代码,使用开源项目CGLib直接操作字节码。

 

 

package org.star_java.jvm.memory;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * VM Args -XX:PermSize=10m -XX:MaxPermSize=10m -XX:+HeapDumpOnOutOfMemoryError
 */
public class JavaMethodAreaOOM
{
	static class OOMObject{}
	
	public static void main(String[] args)
	{
		while (true)
		{
			Enhancer enhancer = new Enhancer();
			enhancer.setSuperclass(OOMObject.class);
			enhancer.setUseCache(false);
			enhancer.setCallback(new MethodInterceptor()
			{
				@Override
				public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable
				{
					return proxy.invokeSuper(obj, args);
				}
			});
			enhancer.create();
		}
	}
}

 

 

运行结果:

 

 

java.lang.OutOfMemoryError: PermGen space

Dumping heap to java_pid8464.hprof ...

Exception in thread "main" Heap dump file created [3855706 bytes in 0.308 secs]

 

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

 

 

我们可以使用一些工具查看生成的内存转储快照,以下是使用 jvisualvm 查看的结果

 


 

可以看出, 我们使用CGLib创建了很多的类,造成了溢出

 

注:本例并非是一个纯粹的实验环境,当前的很多主流框架,如spring,hibernate,都会使用到CGLib这类字节码技术,这就需要方法区保证足够大来装载这些动态生成的Class,如在使用了CGLib技术的地方,大量JSP或动态生成大量jsp文件,给予OSGI 的应用等清况,都需要注意方法区的溢出

 

 

4.本机直接内存溢出

 

DirectMemory的容量可以通过 -XX:MaxDirectMemorySize指定,如果不指定,则默认与java堆的大小一样(-Xmx)。此处,我们使用原作者的代码,使用Unsafe类直接申请本地内存

 

 

package org.star_java.jvm.memory;

import java.lang.reflect.Field;

import sun.misc.Unsafe;

/**
 * VM Args -Xms20m -XX:MaxDirectMemorySize=10m 
 */
public class DirectMemoryOOM
{
	private static final int _1MB = 1024 * 1024;
	
	public static void main(String[] args) throws Exception
	{
		Field unsafeField = Unsafe.class.getDeclaredFields()[0];
		unsafeField.setAccessible(true);
		Unsafe unsafe = (Unsafe) unsafeField.get(null);
		while (true)
		{
			unsafe.allocateMemory(_1MB);
		}
	}
}
 

运行结果:

 

 

Exception in thread "main" java.lang.OutOfMemoryError

at sun.misc.Unsafe.allocateMemory(Native Method)

at org.star_java.jvm.memory.DirectMemoryOOM.main(DirectMemoryOOM.java:21)

 

====================================================================================================

 

以上是JVM对内存的解释,划分以及使用。主要代码演示了使JVM内存溢出的方法,

在自己的编程也要多加注意,多增加一些调试此类异常的经验

 

 

  • 大小: 69 KB
  • 大小: 100.9 KB
  • 大小: 105.1 KB
分享到:
评论

相关推荐

    JAVA学习经典笔记-----2

    6. **高性能:** Java虚拟机(JVM)通过即时编译(JIT)技术提高程序的执行速度。 7. **多线程:** Java内置对多线程的支持,简化了并发程序的开发。 #### 三、Java开发环境配置 1. **Linux环境:** - 配置`JAVA_HOME...

    学习笔记之java虚拟机

    ### 学习笔记之Java虚拟机详解 #### 运行时数据区域概览 Java虚拟机(JVM)运行时数据区域主要包括以下几部分:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区以及运行时常量池。 1. **程序计数器**: -...

    狂神说JVM探究.rar

    【狂神说JVM探究】是一份集合了多种格式的学习资料,主要涵盖了Java虚拟机(JVM)的基础知识。这份资料出自B站上的【狂神说Java】系列教程,为快速入门JVM提供了详实的笔记。以下是根据这些资源可能包含的一些关键...

    理解虚拟机--有笔记版

    除了上述提到的基础知识点外,《深入理解Java虚拟机——JVM高级特性与最佳实践(第2版)》这本书籍还深入探讨了JVM的性能调优、并发编程、以及各种高级特性的具体应用。比如,对于性能调优,书中讲解了如何根据不同的...

    java虚拟机学习笔记进阶篇

    Java虚拟机(JVM)是Java程序的核心组成部分,它负责执行字节码并管理程序的内存。本篇文章将深入探讨Java虚拟机中的垃圾收集器(GC)及其对内存管理的影响。 1. 垃圾收集器的由来与作用 垃圾收集器的引入主要是...

    韩顺平编写的java学习笔记(全)

    - **Java程序运行**: Java程序需要在Java虚拟机(JVM)上运行。这意味着只要系统安装了合适的JVM,Java程序就可以在这个平台上运行。 #### 开发流程简述 1. **编写源文件**:使用`.java`扩展名保存源代码。 2. **...

    Java学习笔记——良葛格

    Java以其“一次编写,到处运行”的特性赢得了全球程序员的喜爱,它的跨平台能力得益于Java虚拟机(JVM)。 接着,笔记会深入讲解Java的语法基础,如变量、数据类型、运算符、流程控制语句(如if、for、while)以及...

    韩顺平老师java视频课程笔记1-13课.doc

    主函数,通常标记为`public static void main(String[] args) {}`,是程序的入口点,JVM(Java虚拟机)将从这里开始执行程序。 ### 数据类型 Java支持多种基本数据类型,包括整数类型、浮点数类型、布尔类型和字符...

    Java笔记---李兴华

    Java源代码先被编译成字节码,然后由Java虚拟机(JVM)解释执行。这种模式既保留了编译型语言的性能优势,又具有解释型语言的灵活性。 通过上述分析,我们可以看出Java不仅仅是一门语言,更是一个庞大的生态系统。...

    深入理解Java虚拟机读书笔记之:第3章 安全(2)

    总的来说,"深入理解Java虚拟机读书笔记之:第3章 安全(2)"主要涵盖了Java安全体系的核心概念,包括类加载器、权限模型、安全管理器以及相关工具的使用。理解这些内容对于任何希望构建安全、可靠的Java应用程序的...

    java学习笔记-基础

    2. **JRE(Java运行时环境)**:包含Java虚拟机(JVM)、类库和其他支持文件,允许在没有安装JDK的计算机上运行Java应用程序。 #### 二、Java语言特性 Java是一种面向对象的编程语言,具备以下特点: 1. **简单性...

    Java学习笔记(必看经典).doc

    9. **Java虚拟机(JVM)**:Java程序被编译成字节码后,由JVM负责解释执行。JVM是Java平台的核心,它实现了跨平台的能力,并通过垃圾回收机制自动管理内存。 10. **Java标准库**:Java的API包含了大量预定义的类和...

    java学习笔记

    - Java程序需在Java虚拟机(JVM)上运行,因此任何装有兼容JVM的操作系统均能执行Java程序。 - 开发步骤包括编写源文件、编译源文件为类文件,最后在虚拟机上运行。 - **注释:** - 单行注释:`//` - 多行注释:`...

    java基础总结大全(笔记).pdf

    - JVM(Java Virtual Machine)是Java虚拟机,它是Java跨平台的关键,负责执行字节码。 - JRE(Java Runtime Environment)包含了JVM和Java的核心类库,提供了运行Java应用程序的环境。 - JDK(Java Development ...

    jVM学习笔记.ppt

    Java虚拟机(JVM)是Java平台的核心组成部分,它负责运行Java程序,并提供了内存管理、垃圾回收以及类加载等关键功能。JVM的学习可以从其基本结构、代码编译和执行过程,以及内存管理和垃圾回收机制三个方面进行深入...

    java se学习笔记

    10. **Java虚拟机(JVM)**: - **内存模型**:堆、栈、方法区、本地方法栈和程序计数器的理解。 - **垃圾回收(GC)**:理解垃圾回收的工作机制,以及内存泄漏的问题。 以上就是【Java SE学习笔记】可能覆盖的...

    java学习笔记整理

    这是因为Java代码会被编译成字节码,然后由Java虚拟机(JVM)解释执行。JVM是Java技术的核心,它负责加载、验证、执行类文件,并且具备垃圾回收机制,能自动管理内存。此外,Java还有安全性、高性能和可靠性等优点。...

    尚硅谷JAVA基础笔记吐血整理

    它的设计目标是实现“一次编写,到处运行”,通过Java虚拟机(JVM)确保代码在不同操作系统上都能运行。Java语言的特点包括简洁性、面向对象、健壮性、安全性、高效性和可移植性。 【基本语法】 Java的基本语法包括...

    飞加Java学习笔记_内存管理

    - **堆(Heap)内存**:这是Java虚拟机(JVM)用来存储所有对象实例的地方。当通过`new`关键字创建对象时,对象就会被分配在堆内存中。堆内存的大小可以根据需要动态调整,但最终受到物理内存的限制。堆内存由垃圾...

Global site tag (gtag.js) - Google Analytics