- 浏览: 1428638 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (363)
- oracle (43)
- 缓存策略 (4)
- 数据库设计 (7)
- IntelliJ IDEA (8)
- freemarker (3)
- JSP (12)
- java基础 (75)
- tomcat (14)
- 服务器 (10)
- maven (3)
- linux (21)
- e-learning (2)
- 手机开发 (1)
- 设计模式 (6)
- 技术之外 (2)
- 工具的使用 (8)
- HTML 5 (5)
- 网站前台 (38)
- 网站后台 (11)
- 项目管理 (12)
- 面试题 (5)
- 幽默 (0)
- 系统架构 (8)
- 创业 (10)
- div-css (5)
- 诗词歌赋 (1)
- 网络课堂组知识库 (4)
- 杂家 (3)
- android (12)
- 框架 (14)
- 读书笔记 (1)
- 孙子兵法 (1)
- mysql (3)
- 小人书 (0)
- Jquery (6)
- eclipse (2)
- 正则表达式 (1)
最新评论
-
a98709474:
写的很详细,看完了,明白了这种概念了
数据库水平切分(拆库拆表)的实现原理解析(转) -
a98709474:
MYSQL分库分表总结 -
CatchU:
7年前的招聘要求,厉害厉害
面试要求 -
luozhixiong:
<table class="bbcode&qu ...
MYSQL分库分表总结 -
沈寅麟:
好用
freemarker格式化
如果JVM里运行的程序, 它的内存堆和持久存储区域的都满了,这个时候程序还想创建对象实例的话,垃圾收集器就会启动,试图释放足够的内存来创建这个对象。这个时候如果垃圾收集器 没有能力释放出足够的内存,它就会抛出OutOfMemoryError内存溢出错误。
在抛出内存溢出错误的时候,一般都会提示内存泄露的种类,
1.堆(heap)内存泄漏
java.lang.OutOfMemoryError: Javaheap space:
大家都比较熟悉 ,通过设置-Xms2048m -Xmx4096m可以解决
2.栈(stack)内存泄漏:
stack over flow当前线程运行期间维护的中间变量等信息过多,
例如常见的死循环引起stack over flow
3.方法区(permanent heap)内存泄漏
java.lang.OutOfMemoryError: PermGen space:
发生的原因和类型装载、类型卸载有直接的关系,
通过设置-XX:MaxNewSize=256m -XX:MaxPermSize=256m可以解决。 一般情况下,当服务器内存过小,而提供了大量的访问服务时, 可能会缓存过多的数据对象造成堆内存溢出,当web应用不断扩大,
加载的lib库达到一定大小(4M)后,
就容易报PermGen OOM,也就是方法区溢出。
在Linux服务器中将参数写入环境变量:
export CATALINA_OPTS="-Xms2048m -Xmx4096m"
export JAVA_OPTS="-XX:MaxNewSize=256m -XX:MaxPermSize=256m"
Xmx 最大不要超过服务器物理内存的80%
1. 栈溢出实验
什么时候会让 Java 栈溢出啊?栈的基本特点就是 FILO(First In Last Out),如果 in 的太多而 out 的太少,就好 overflow 了。而 Java Method Stack 的功能就是保存每一次函数调用时的“现场”,即为入栈,函数返回就对应着出栈,所以函数调用的深度越大,栈就变得越大,足够大的时候就会溢出。所以模拟 Java Method Stack 溢出,只要不断递归调用某一函数就可以。
运行结果
2. Heap 内存溢出
堆是用来存储对象的,当然对象不一定都存在堆里(由于逃逸技术的发展)。那么堆如果溢出了,一定是不能被杀掉的对象太多了。模拟 Heap 内存溢出,只要不断创建对象并保持有引用存在即可。
运行结果
3. Method Area 内存溢出
也就是 Non-heap,是用来存储 Object Class Data、常量、静态变量、JIT 编译后的代码等。如果该区域溢出,则说明某种数据创建的实在是太多了。模拟的话,可以不断创建新的 class,直到溢出为止。
以下代码使用到 cglib-2.2.2.jar 和 asm-all-3.0.jar。
运行结果
4. Runtime Constant Pool in Method Area 内存溢出
在运行时产生大量常量就可以实现让 Method Area 溢出的目的。运行是常量可以用 String 类的 intern 方法,不断地产生新的常量。
运行结果
结语
在实际编码中要尽量避免此类错误。不过大多数程序设计的结构比这里的示例要复杂的多,使得问题被隐藏。但 JVM 的内存溢出问题本质上大都可归结为以上这几种情况。
补充介绍 cglib 和 asm
JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理。JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包。
CGLIB是一个强大的高性能的代码生成包。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。最流行的OR Mapping工具hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的)。EasyMock和jMock是通过使用模仿(moke)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。除了CGLIB包,脚本语言例如Groovy和BeanShell,也是使用ASM来生成java的字节码。当不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
在抛出内存溢出错误的时候,一般都会提示内存泄露的种类,
1.堆(heap)内存泄漏
java.lang.OutOfMemoryError: Javaheap space:
大家都比较熟悉 ,通过设置-Xms2048m -Xmx4096m可以解决
2.栈(stack)内存泄漏:
stack over flow当前线程运行期间维护的中间变量等信息过多,
例如常见的死循环引起stack over flow
3.方法区(permanent heap)内存泄漏
java.lang.OutOfMemoryError: PermGen space:
发生的原因和类型装载、类型卸载有直接的关系,
通过设置-XX:MaxNewSize=256m -XX:MaxPermSize=256m可以解决。 一般情况下,当服务器内存过小,而提供了大量的访问服务时, 可能会缓存过多的数据对象造成堆内存溢出,当web应用不断扩大,
加载的lib库达到一定大小(4M)后,
就容易报PermGen OOM,也就是方法区溢出。
在Linux服务器中将参数写入环境变量:
export CATALINA_OPTS="-Xms2048m -Xmx4096m"
export JAVA_OPTS="-XX:MaxNewSize=256m -XX:MaxPermSize=256m"
Xmx 最大不要超过服务器物理内存的80%
1. 栈溢出实验
什么时候会让 Java 栈溢出啊?栈的基本特点就是 FILO(First In Last Out),如果 in 的太多而 out 的太少,就好 overflow 了。而 Java Method Stack 的功能就是保存每一次函数调用时的“现场”,即为入栈,函数返回就对应着出栈,所以函数调用的深度越大,栈就变得越大,足够大的时候就会溢出。所以模拟 Java Method Stack 溢出,只要不断递归调用某一函数就可以。
public class Test { private int stackLength = 0; public void stackOverflow() { ++stackLength; stackOverflow(); } public static void main(String[] args) throws Throwable { Test test = new Test(); try { test.stackOverflow(); } catch (Throwable e) { System.out.println("stack length: " + test.stackLength); throw e; } } }
运行结果
stack length: 1052 Exception in thread "main" java.lang.StackOverflowError at com.sinosuperman.main.Test.stackOverflow(Test.java:8) at com.sinosuperman.main.Test.stackOverflow(Test.java:9) at com.sinosuperman.main.Test.stackOverflow(Test.java:9) at com.sinosuperman.main.Test.stackOverflow(Test.java:9) at com.sinosuperman.main.Test.stackOverflow(Test.java:9) ...
2. Heap 内存溢出
堆是用来存储对象的,当然对象不一定都存在堆里(由于逃逸技术的发展)。那么堆如果溢出了,一定是不能被杀掉的对象太多了。模拟 Heap 内存溢出,只要不断创建对象并保持有引用存在即可。
package com.sinosuperman.main; import java.util.ArrayList; import java.util.List; public class Test { private static class HeapOomObject { } public static void main(String[] args) { List<HeapOomObject> list = new ArrayList<HeapOomObject>(); while (true) { list.add(new HeapOomObject()); } } }
运行结果
[GC 17024K->14184K(49088K), 0.1645899 secs] [GC 26215K->29421K(49088K), 0.0795283 secs] [GC 35311K(49088K), 0.0095602 secs] [Full GC 43400K->37709K(49088K), 0.1636702 secs] [Full GC 49088K->45160K(49088K), 0.1609499 secs] [GC 45312K(49088K), 0.0265257 secs] [Full GC 49088K->49087K(49088K), 0.1656715 secs] [Full GC 49087K->49087K(49088K), 0.1656147 secs] [Full GC 49087K->49062K(49088K), 0.1976727 secs] [GC 49063K(49088K), 0.0287960 secs] [Full GC 49087K->49087K(49088K), 0.1901410 secs] [Full GC 49087K->49087K(49088K), 0.1673056 secs] [Full GC 49087K->316K(49088K), 0.0426515 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at com.sinosuperman.main.Test.main(Test.java:14)
3. Method Area 内存溢出
也就是 Non-heap,是用来存储 Object Class Data、常量、静态变量、JIT 编译后的代码等。如果该区域溢出,则说明某种数据创建的实在是太多了。模拟的话,可以不断创建新的 class,直到溢出为止。
以下代码使用到 cglib-2.2.2.jar 和 asm-all-3.0.jar。
package com.sinosuperman.main; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class Test { static class MethodAreaOomObject { } public static void main(String[] args) { while(true){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MethodAreaOomObject.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { return proxy.invoke(obj, args); } }); enhancer.create(); } } }
运行结果
Exception in thread "main" net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237) at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285) at com.sinosuperman.main.Test.main(Test.java:24) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384) at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219) ... 3 more Caused by: java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) at java.lang.ClassLoader.defineClass(ClassLoader.java:615) ... 8 more
4. Runtime Constant Pool in Method Area 内存溢出
在运行时产生大量常量就可以实现让 Method Area 溢出的目的。运行是常量可以用 String 类的 intern 方法,不断地产生新的常量。
package com.sinosuperman.main; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { List<String> list = new ArrayList<String>(); int i = 0; while (true) { list.add(String.valueOf(i++).intern()); } } }
运行结果
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space at java.lang.String.intern(Native Method) at com.sinosuperman.main.Test.main(Test.java:12)
结语
在实际编码中要尽量避免此类错误。不过大多数程序设计的结构比这里的示例要复杂的多,使得问题被隐藏。但 JVM 的内存溢出问题本质上大都可归结为以上这几种情况。
补充介绍 cglib 和 asm
JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理。JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包。
CGLIB是一个强大的高性能的代码生成包。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。最流行的OR Mapping工具hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的)。EasyMock和jMock是通过使用模仿(moke)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。除了CGLIB包,脚本语言例如Groovy和BeanShell,也是使用ASM来生成java的字节码。当不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
发表评论
-
打印IP 来源
2014-10-16 22:07 937<% String userAgent = reques ... -
java 写文本换行
2014-08-08 18:34 1950import org.apache.commons.io.Fi ... -
DBCP连接池配置示例
2014-06-17 11:44 1238<bean id="dataSourceOra ... -
CGLIB与asm
2014-05-05 14:42 1341“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言 ... -
201404转成 2014.04
2014-03-31 17:45 984public static void main(Str ... -
取出 字符串中的 网址
2013-10-15 17:47 1255public static void main(Str ... -
java反国际化
2013-09-23 18:10 1004public static String fromEn ... -
AtomicInteger与Volatile修饰
2013-02-05 11:50 6040今天写代码,尝试使用了AtomicInteger这个类,感觉 ... -
ExecutorService线程池
2013-02-05 11:40 1618http://blog.sina.com.cn/s/blog ... -
web.xml中load-on-startup的作用
2012-12-24 10:06 1657如下一段配置,熟悉DWR的再熟悉不过了: <servle ... -
最新版本
2012-09-13 09:28 1004Java SE 7u7 apache-tomcat-7.0. ... -
格式化数字
2012-09-10 20:12 901public static void main(Str ... -
用apache common io包获得文件扩展名
2012-09-09 23:11 1362apache common io包包含了很多非常实用的工具类, ... -
值传递,引用传递
2012-07-28 23:29 1134java 对于 8种基本类型 和 他们的包装类型 , 外 ... -
代码之丑
2012-07-07 22:01 2325原文:http://www.infoq.com/cn/news ... -
Memcache
2012-06-27 09:36 1038Memcache是一个高性能的分布式的内存对象缓存系统,通过在 ... -
ActiveMQ
2012-06-14 15:09 15150ActiveMQ 是Apache出品,最流行的,能力强劲的开源 ... -
proxool配置
2012-06-12 11:43 1178项目结构 所需jar包 proxool.prope ... -
各种文件的注释
2012-04-23 10:44 997<%-- comment --%> JSP注释,也称为“隐藏注 ... -
List排序
2012-03-27 20:18 1193集合类List存放的数据,默认是按照放入时的顺序存放的,比如依 ...
相关推荐
### Maven内存溢出解决方案 #### 一、引言 在使用Maven进行项目构建时,尤其是在处理大型项目或执行资源密集型任务(如`mvn site`)时,经常会遇到Java堆空间溢出的问题。这类问题通常是由于Maven运行所需的内存...
### Eclipse内存溢出问题解析与解决方案 #### 一、内存溢出概述 内存溢出(Memory Leak)是指程序运行过程中使用的内存超过系统所能提供的最大内存限制时所出现的问题。这种情况通常发生在Java等需要进行垃圾回收...
"java内存泄漏与内存溢出关系解析" java内存泄漏与内存溢出关系解析是java开发者需要了解的重要知识点之一。下面我们将详细介绍java内存泄漏与内存溢出的关系、原因和解决方法。 一、内存泄漏和内存溢出的定义 ...
内存溢出(Out of Memory)是指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,那么结果就是内存不够用,此时就会报错OOM,即所谓的内存...
缓冲溢出是一种常见的计算机安全漏洞,它源于程序处理数据时对内存空间的不当管理。在程序设计中,当一个变量或数据结构(如数组)的存储空间被超过其预设容量的数据填充时,就会发生缓冲区溢出。这种现象可能导致...
首先,我们需要了解缓冲区溢出的分类。常见的有栈溢出、堆溢出、全局变量溢出等。栈溢出是最常见的一种,由于函数调用时的返回地址通常保存在栈上,攻击者可以通过溢出修改这个地址,使程序跳转到恶意代码的位置执行...
然而,直接用HashMap处理40亿个整数会导致内存溢出,因为每个记录需要8字节(4字节的键和4字节的值)。1GB内存只能容纳约1亿条记录,远不足以存储所有数据。 为了解决这个问题,我们需要将大数据分片处理。这可以...
一、内存越界的定义和分类 内存越界是指在计算机程序中,因为访问或修改了超出变量或数组的边界而导致的错误。内存越界可能会导致程序崩溃、内存泄漏、数据丢失等严重问题。在 Linux C 语言中,内存越界问题非常...
Memory Leak 是最难排查调试的 Bug 种类之一,因为内存泄漏是个 undecidable problem,只有开发者才能明确一块内存是不是需要被回收。再加上内存泄漏也没有特定的报错信息,只能通过一定时间段的日志来判断是否存在...
**三、缓冲区溢出分类** 1. **栈溢出**:发生在栈内存区域,常因函数调用时的局部变量溢出。 2. **堆溢出**:发生在程序动态分配的内存(堆)上,溢出可能导致堆管理结构破坏。 3. **整型溢出**:当整数运算超出其...
#### 缓冲区溢出攻击的分类 缓冲区溢出攻击主要可以分为两大类: 1. **栈溢出**:通常发生在函数调用过程中,由于栈帧的特性,可以通过向较小的缓冲区写入超出其容量的数据来覆盖函数的返回地址。 2. **堆溢出**:...
3. **易语言内存操作**:教授如何使用易语言的内建函数或模块来查询和操作内存,如读取、写入内存,以及如何处理内存溢出等问题。 4. **虚拟内存设置**:介绍如何在系统层面调整虚拟内存的大小和位置,以优化系统...
4. 缓冲区溢出攻击的分类 5. 缓冲区溢出攻击的防范策略 6. 编译器的安全检查 7. 边界检查 8. 地址空间布局随机化 9. 数据执行保护 10. 缓冲区溢出攻击的挑战 11. 缓冲区溢出攻击的防范需要多方面的合作
分配的对象包含保护字段,以帮助调试缓冲区溢出。 四、Stats统计信息 在调试模式中,DPDK Mempool库从池中获取、释放的统计信息存放在mempool结构体中。为了避免并发访问统计计数器,统计信息是per-lcore的。 五...
内存错误的种类很多,包括缓冲区 Underflow、缓冲区溢出、多次释放同一内存块和缓慢的内存泄漏。这些错误可以分为两大类:堆损坏和内存泄漏。 堆损坏是指在内存中分配的内存块被损坏或修改,导致程序崩溃或出现不可...
1. 内存溢出:当程序试图写入超出分配内存边界的数据时,就可能发生溢出。这可能覆盖相邻的数据,破坏程序的正常运行,甚至使攻击者能够篡改关键信息。 2. 指针错误:循环写可能导致指针失效,使得指针不再指向合法...
本文将对内存越界问题进行总结,包括内存越界的种类、现象及引起的原因。 进程地址空间的分配 在 Linux 中,每个进程都有其自己的地址空间,包括代码段、数据段、栈段和堆段。栈段是由操作系统自动分配的,用于...