内存泄漏代码_调查内存泄漏第1部分–编写泄漏代码

内存泄漏代码

前几天,我发现了这个小问题:该服务器运行了一段时间,然后掉下来了。 然后通过启动脚本重新启动,整个过程重复进行。 听起来并没有什么坏处,因为它虽然对数据造成了重大损失,但对业务的重要性并不高,所以我决定仔细研究一下,找出问题出在哪里。 首先要注意的是,服务器通过了所有的单元测试和大量的集成测试。 它在使用测试数据的所有测试环境中都能很好地运行,那么生产中出了什么问题? 很容易猜到,在生产中,它的负载可能比测试重,或者比设计所允许的负载大,因此它耗尽了资源,但是什么资源以及在哪里呢? 这是一个棘手的问题。 屏幕快照2013-11-11 at 08.57.22

为了演示如何研究此问题,首先要做的是编写一些泄漏的示例代码,而我将使用Producer Consumer模式进行此操作,因为我可以演示它的大问题。

为了演示泄漏的代码1,我需要像往常一样需要一个高度人为的方案,并且在此方案中,假设您在一个将其股票和股票销售记录在数据库中的系统上为股票经纪工作。 订单由一个简单的线程接收并放入队列中。 然后,另一个线程从队列中获取订单,并将其写入数据库。 的
POJO Order非常简单,如下所示:

public class Order { private final int id; private final String code; private final int amount; private final double price; private final long time; private final long[] padding; /** * @param id *            The order id * @param code *            The stock code * @param amount *            the number of shares * @param price *            the price of the share * @param time *            the transaction time */ public Order(int id, String code, int amount, double price, long time) { super(); this.id = id; this.code = code; this.amount = amount; this.price = price; this.time = time; // This just makes the Order object bigger so that // the example runs out of heap more quickly. this.padding = new long[3000]; Arrays.fill(padding, 0, padding.length - 1, -2); } public int getId() { return id; } public String getCode() { return code; } public int getAmount() { return amount; } public double getPrice() { return price; } public long getTime() { return time; } }

Order POJO是简单的Spring应用程序的一部分,该应用程序具有三个关键抽象,当Spring调用它们的start()方法时,它们会创建一个新线程。

其中第一个是OrderFeed 。 它的run()方法创建一个新的虚拟订单并将其放置在队列中。 然后,它会Hibernate片刻,然后再创建下一个订单。

public class OrderFeed implements Runnable { private static Random rand = new Random(); private static int id = 0; private final BlockingQueue<Order> orderQueue; public OrderFeed(BlockingQueue<Order> orderQueue) { this.orderQueue = orderQueue; } /** * Called by Spring after loading the context. Start producing orders */ public void start() { Thread thread = new Thread(this, "Order producer"); thread.start(); } /** The main run loop */ @Override public void run() { while (true) { Order order = createOrder(); orderQueue.add(order); sleep(); } } private Order createOrder() { final String[] stocks = { "BLND.L", "DGE.L", "MKS.L", "PSON.L", "RIO.L", "PRU.L", "LSE.L", "WMH.L" }; int next = rand.nextInt(stocks.length); long now = System.currentTimeMillis(); Order order = new Order(++id, stocks[next], next * 100, next * 10, now); return order; } private void sleep() { try { TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } 
}

第二类是OrderRecord ,它负责从队列中获取订单并将其写入数据库。 问题在于将订单写入数据库要花费的时间要长得多。 我的recordOrder(…)方法中有1秒的长时间睡眠,这证明了这一点。

public class OrderRecord implements Runnable { private final BlockingQueue<Order> orderQueue; public OrderRecord(BlockingQueue<Order> orderQueue) { this.orderQueue = orderQueue; } public void start() { Thread thread = new Thread(this, "Order Recorder"); thread.start(); } @Override public void run() { while (true) { try { Order order = orderQueue.take(); recordOrder(order); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * Record the order in the database * * This is a dummy method * * @param order *            The order * @throws InterruptedException */ public void recordOrder(Order order) throws InterruptedException { TimeUnit.SECONDS.sleep(1); } }

结果很明显: OrderRecord线程无法跟上,队列将变得越来越长,直到JVM用完堆空间并OrderRecord为止。 这是生产者-消费者模式的最大问题:消费者必须能够跟上生产者的发展。

为了证明他的观点,我添加了第三类OrderMonitor ,该类每隔几秒钟打印一次队列大小,以便您可以看到出现问题的地方。

public class OrderQueueMonitor implements Runnable { private final BlockingQueue<Order> orderQueue; public OrderQueueMonitor(BlockingQueue<Order> orderQueue) { this.orderQueue = orderQueue; } public void start() { Thread thread = new Thread(this, "Order Queue Monitor"); thread.start(); } @Override public void run() { while (true) { try { TimeUnit.SECONDS.sleep(2); int size = orderQueue.size(); System.out.println("Queue size is:" + size); } catch (InterruptedException e) { e.printStackTrace(); } } } }

为了完成阵容,我在下面添加了Spring上下文:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd" default-init-method="start" default-destroy-method="destroy"><bean id="theQueue" class="java.util.concurrent.LinkedBlockingQueue"/><bean id="orderProducer" class="com.captaindebug.producerconsumer.problem.OrderRecord"><constructor-arg ref="theQueue"/></bean><bean id="OrderRecorder" class="com.captaindebug.producerconsumer.problem.OrderFeed"><constructor-arg ref="theQueue"/></bean><bean id="QueueMonitor" class="com.captaindebug.producerconsumer.problem.OrderQueueMonitor"><constructor-arg ref="theQueue"/></bean></beans>

下一步是启动泄漏的示例代码。 您可以通过转到以下目录来执行此操作

/<your-path>/git/captaindebug/producer-consumer/target/classes

…然后键入以下命令:

java -cp /path-to/spring-beans-3.2.3.RELEASE.jar:/path-to/spring-context-3.2.3.RELEASE.jar:/path-to/spring-core-3.2.3.RELEASE.jar:/path-to/slf4j-api-1.6.1-javadoc.jar:/path-to/commons-logging-1.1.1.jar:/path-to/spring-expression-3.2.3.RELEASE.jar:. com.captaindebug.producerconsumer.problem.Main

…其中“ path-to ”是您的jar文件的路径

有一两件事,我真的很讨厌关于Java的是,事实上,它是如此难以运行在命令行中的任何程序。 您必须弄清楚什么是类路径,需要设置哪些选项和属性以及什么是主类。 当然,肯定有可能想到一种简单地键入Java programName的方法,并且JVM找出所有内容的位置,特别是如果我们开始使用约定而不是配置:它有多难?

您还可以通过附加一个简单的jconsole来监视泄漏的应用程序。 如果要远程运行它,则需要在上面的命令行中添加以下选项(选择您自己的端口号):

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9010 
-Dcom.sun.management.jmxremote.local.only=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false

…如果您查看使用的堆数量,您会发现随着队列变大,堆逐渐增加。

屏幕截图2013-11-11 at 08.57.47

如果一千字节的内存泄漏了,那么您可能永远也找不到它。 如果一千兆字节的内存泄漏,问题将很明显。 因此,目前要做的就是坐下来等待一些内存泄漏,然后再继续进行下一步调查。 下次再说…

1源代码可以在我在GitHub上的Producer Consumer项目中找到 。

参考: 调查内存泄漏第1部分–在Captain Debug的Blog博客上,由JCG合作伙伴 Roger Hughes 编写泄漏代码 。

翻译自: https://www.javacodegeeks.com/2013/12/investigating-memory-leaks-part-1-writing-leaky-code.html

内存泄漏代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【渝粤教育】广东开放大学 广东开放大学学习指引 形成性考核 (28)

题库查询系统 选择题 题目&#xff1a;在开放大学的学习中认识同学可以增强开放大学学生间的交流与友情&#xff0c;促进学生对开放大学的归属感与认同感&#xff0c;克服学习中的孤独感。 答案&#xff1a; A、“对”。 题目&#xff1a;广东开放大学服务于广东学习型社会&…

【渝粤教育】广东开放大学 法理学 形成性考核 (46)

题库查询系统 选择题 题目&#xff1a;法理学与部门法的关系是&#xff08; &#xff09;的关系。 答案&#xff1a; A、理论与实际 B、 一般与特殊 C、 整体与局部 D、论与史 题目&#xff1a;法的最终决定因素是&#xff08;&#xff09;。 答案&#xff1a; A、阶级斗争状况…

android 打印kernel log,android8.0 kernel4.9.44 各层log打开

一.问题平台android8.0 kernel4.9.44&#xff0c;想加个i2c驱动&#xff0c;打开log都是一件脑瓜疼的事。二.log总结android有三种log。1.kernel下面的&#xff0c;就是driver层log。2.kernel上面的&#xff0c;init和init.rc启动的程序的log&#xff0c;应用层3.kernel上面的&…

【渝粤教育】广东开放大学 网络完全与技术 形成性考核 (44)

题库查询系统 选择题 题目&#xff1a;以下哪个不属于数字签名的功能( ) 答案&#xff1a; A、不可伪造的 B、可重用的 C、可信的 D、不可抵赖的 题目&#xff1a;前缀为Worm的病毒是( ) 答案&#xff1a; A、蠕虫病毒 B、后门病毒 C、杩 D、脚本病毒 题目&#xff1a;下面关于…

Java整数缓存-为什么Integer.valueOf(127)== Integer.valueOf(127)为True

在一次采访中&#xff0c;我的一个朋友被问到如果我们有两个Integer对象&#xff0c; Integer a 127; Integer b 127; Integer a 127; Integer b 127; 为什么当a b都持有两个单独的对象时&#xff0c;其值为true &#xff1f; 在本文中&#xff0c;我将尝试回答这个问题&a…

【渝粤教育】广东开放大学 中国法律史 形成性考核 (31)

题库查询系统 选择题 题目&#xff1a;春秋时期在晋国铸刑鼎的是 答案&#xff1a; A、赵鞅 题目&#xff1a;汉代的买卖契约叫做 答案&#xff1a; A、券书 题目&#xff1a;西周法官在审判中判断当事人陈述真伪的方式叫做 答案&#xff1a; A、“五听” 题目&#xff1a;明朝…

高鸿股份与鸿蒙,高鸿股份(000851)个股分析_牛叉诊股_同花顺财经

资金净流入资金净流出行业平均线[{"date":"2021-04-14","value":"1028.65","field":null},{"date":"2021-04-15","value":"213.51","field":null},{"date":&q…

【渝粤教育】广东开放大学 会展项目管理 形成性考核 (59)

题库查询系统 选择题 题目&#xff1a;为了确保项目团队和其他项目干系人完全理解并且投入到项目&#xff0c;目标必须是&#xff1f; 答案&#xff1a; A、现实的和可达到的 题目&#xff1a;在一定的组织里&#xff0c;一个项目一般不会正式启动&#xff0c;除非完成了&#…

【渝粤教育】广东开放大学 原画设计 形成性考核 (23)

题库查询系统 选择题 题目&#xff1a;在图层蒙版里用黑色画笔涂抹&#xff0c;可以遮盖住图层内相对应位置的图像信息 答案&#xff1a; A、正确 题目&#xff1a;图层样式描边的描边是根据选区边缘或路径来做描边的 答案&#xff1a; A、正确 题目&#xff1a;魔术橡皮擦工具…

android软解码花屏,视频花屏 · Issue #386 · bilibili/ijkplayer · GitHub

各位大神&#xff0c;还是没法解码ijkmp_set_format_callback(0x10d5e5, 0x17ec4a20)ijkmp_set_format_callback()voidijkmp_set_option_int(start-on-prepared, 1)ijkmp_set_option_int()voidijkmp_ios_set_view(glView0x17d36c10)ijkmp_ios_set_view(glView0x17d36c10)voidij…

【渝粤教育】广东开放大学 土木工程材料 形成性考核 (22)

选择题 题目&#xff1a;下列外加剂不能用于改善混凝土的耐久性的是 。 题目&#xff1a;安定性不良的水泥严禁在工程中使用。 题目&#xff1a;有硫酸盐腐蚀的混凝土工程应优先选择&#xff08; &#xff09;水泥 题目&#xff1a;有耐热要求的混凝土工程&#xff0c;应优先选…

记事本写html怎么加a1图片,记事本-功能待添加

IO流、图形化用户界面、事件监听import java.awt.event.*;import javax.swing.*;import java.io.*;public class Jsb extends JFrame implements ActionListener{JMenuBar cd;JMenu cd1,cd2;JMenuItem cdx1,cdx2;JTextArea wby;JScrollPane gd;public static void main(String[…

orika 映射非空字段_Orika:将JAXB对象映射到业务/域对象

orika 映射非空字段这篇文章着眼于使用Orika将JAXB对象映射到业务域对象。 本月初&#xff0c; 我使用基于反射的Dozer讨论 了相同的映射用例 。 在本文中&#xff0c;我假设需要映射相同的示例类&#xff0c;但是它们将使用Orika而不是Dozer进行映射 。 Dozer和Orika旨在解决…

【渝粤教育】广东开放大学 应用创意写作 形成性考核 (54)

选择题 题目&#xff1a;《四库全书》将图书分为 &#xff08; &#xff09;四部。 题目&#xff1a;“五经”指 &#xff08; &#xff09;。 题目&#xff1a;汉代 &#xff08; &#xff09;在《论六家要旨》中&#xff0c;重点对春秋战国时诸子百家中的儒、墨、名、法、道、…

【渝粤教育】广东开放大学 教育心理学 形成性考核 (42)

选择题 题目&#xff1a;认知过程不包括以下哪种要素&#xff08;&#xff09; 题目&#xff1a;下列说法中关于动机的说法中正确的是&#xff08;&#xff09; 题目&#xff1a;关于感觉和知觉下列说法中错误的是 &#xff08; &#xff09; 题目&#xff1a;下列关于意识和无…

使用Maven将文件上传和下载到S3

多年来&#xff0c;我已经看到许多团队以许多不同的方式使用Maven。 Maven可用于许多ci / cd任务&#xff0c;而无需使用额外的管道代码&#xff0c;或者可用于在运行某些测试之前准备开发环境。 通常&#xff0c;它是一种方便的工具&#xff0c;在Java团队中广泛使用&#xf…

html怎么把一段文字设置为连接到下一个网页的按钮,网页设计三合一模拟试题(一)...

网页设计三合一模拟试题一、选择题&#xff1a;(20小题&#xff0c;每题2分&#xff0c;共40分)1、以下超链接到电子邮件的正确格式是&#xff1a;()A. maiil to://abchttp://www.doczj.com/doc/e97fe8f9b9f67c1cfad6195f312b3169a451eaf7.htmlB. mail to: abchttp://www.doczj…

【渝粤教育】广东开放大学 演讲与口才 形成性考核 (1)

题库查询系统 选择题 题目&#xff1a;口才是人际交流的润滑剂。 答案&#xff1a; A、对 题目&#xff1a;说话的水平决定了沟通的成败。 答案&#xff1a; A、对 题目&#xff1a;能说话≠有口才。 答案&#xff1a; A、对 题目&#xff1a;会说话≠有口才。 答案&#xff1a…

怎么删除计算机管理员用户密码,小编手把手教你Win10系统如何删除管理员账户密码...

一位用户反馈自己在windows10正式版系统电脑中设置了管理员账户密码&#xff0c;之后每次开机都需要输入密码才可以登录&#xff0c;感觉十分麻烦。那么&#xff0c;Win10系统下该如何删除管理员账户密码&#xff1f;接下来&#xff0c;系统之家小编就为大家分享下具体操作方法…

【渝粤教育】广东开放大学 质量认证认可 形成性考核 (31)

题库查询系统 选择题 题目&#xff1a; 以下哪个认证标志成为世界上第一个受法律保护的认证标志。&#xff08;&#xff09; 正确答案&#xff1a; 答案&#xff1a; A、 题目&#xff1a; &#xff08;&#xff09;以下哪个标志是国家认监委的标志? 正确答案&#xff1a; 答…