如何分析堆外内存使用情况_堆上与堆外的内存使用情况

如何分析堆外内存使用情况

总览

最近有人问我在Java中使用堆内存的好处和智慧。 面临相同选择的其他人可能会对这些答案感兴趣。

堆外内存没什么特别的。 线程堆栈,应用程序代码,NIO缓冲区都在堆外。 实际上,在C和C ++中,您只有非托管内存,因为默认情况下它没有托管堆。 Java中托管内存或“堆”的使用是该语言的一个特殊功能。 注意:Java不是执行此操作的唯一语言。

新的Object()vs对象池vs Off堆内存

新的Object()

在Java 5.0之前,使用对象池非常流行。 创建对象仍然非常昂贵。 但是,从Java 5.0开始,对象分配和垃圾清理变得便宜得多,并且开发人员发现,通过删除对象池并仅在需要时创建新对象,它们可以提高性能,并简化代码。 在Java 5.0之前,几乎所有对象池,甚至是使用对象的对象池都提供了改进,而从Java 5.0池中,只有昂贵的对象才有意义,例如线程,套接字和数据库连接。

对象池

在低延迟空间中,显而易见的是,通过减少对CPU缓存的压力,回收可变对象可以提高性能。 这些对象必须具有简单的生命周期和简单的结构,但是使用它们可以看到性能和抖动方面的显着改善。

使用对象池的另一个有意义的领域是当使用许多重复的对象加载大量数据时。 随着内存使用量的显着减少以及GC必须管理的对象数量的减少,您看到了GC时间的减少和吞吐量的增加。

这些对象池的设计比使用同步HashMap的对象池更轻巧,因此它们仍然有帮助。

以这个StringInterner类为例。 您将所需文本的可循环使用的可变StringBuilder作为字符串传递给它,它将提供匹配的字符串。 传递字符串会很无效率,因为您已经创建了对象。 StringBuilder可以回收。

注意:此结构具有一个有趣的属性,除了最低Java保证提供的安全性之外,不需要任何其他线程安全功能(例如volatile或sync)。 也就是说,您可以正确地看到String中的final字段,并且只能读取一致的引用。

public class StringInterner {private final String[] interner;private final int mask;public StringInterner(int capacity) {int n = Maths.nextPower2(capacity, 128);interner = new String[n];mask = n - 1;}private static boolean isEqual(@Nullable CharSequence s, @NotNull CharSequence cs) {if (s == null) return false;if (s.length() != cs.length()) return false;for (int i = 0; i < cs.length(); i++)if (s.charAt(i) != cs.charAt(i))return false;return true;}@NotNullpublic String intern(@NotNull CharSequence cs) {long hash = 0;for (int i = 0; i < cs.length(); i++)hash = 57 * hash + cs.charAt(i);int h = (int) Maths.hash(hash) & mask;String s = interner[h];if (isEqual(s, cs))return s;String s2 = cs.toString();return interner[h] = s2;}
}

堆外内存使用率

使用堆外内存和使用对象池都有助于减少GC暂停,这是它们唯一的相似之处。 对象池适用于短暂的可变对象,创建对象的成本高以及存在大量重复的不可变对象的长寿命。 中度活泼的可变对象或复杂的对象更有可能由GC处理。 但是,中长寿命的可变对象遭受堆外内存解决的许多方式的困扰。

堆外内存提供;

  • 可扩展至大型内存,例如超过1 TB且大于主内存。
  • 名义上对GC暂停时间的影响。
  • 进程之间共享,减少JVM之间的重复,并使分裂JVM更容易。
  • 持久性,可以更快地重新启动或回复测试中的生产数据。

在设计系统方面,堆外内存的使用为您提供了更多选择。 最重要的改进不是性能,而是确定性。

堆外和测试

高性能计算中的最大挑战之一是再现难以理解的错误,并能够证明已解决了这些错误。 通过以持久方式将所有输入事件和数据存储在堆外,您可以将关键系统转变为一系列复杂的状态机。 (或者在简单的情况下,只有一个状态机)通过这种方式,您可以在测试和生产之间获得可重现的行为和性能。

许多投资银行都使用这种技术来对一天中的任何事件可靠地重播系统,并确切地说明了该事件按原样处理的原因。 更重要的是,一旦你有了一个位置,你可以证明你有固定发生在生产,而不是发现问题,并希望这是问题的问题。

确定性行为与确定性行为一起出现。 在测试环境中,您可以按照实际的时间重播事件,并显示期望在生产中获得的延迟分布。 如果硬件不相同,某些系统抖动将无法重现,但是从统计角度看您可能会非常接近。 为了避免花一天时间重放一天的数据,您可以添加一个阈值。 例如,如果事件之间的时间超过10毫秒,则您可能只能等待10毫秒。 这样一来,您就可以在不到一个小时的时间内按实际时间重播一天的事件,并查看您的更改是否改善了延迟分配。

通过降低级别,您不会失去“一次编译,随处运行”的某些功能吗?

在某种程度上,这是正确的,但远没有您想象的要多。 当您靠近处理器工作时,您将更加依赖处理器或OS的行为方式。 幸运的是,大多数系统使用AMD / Intel处理器,就其提供的低级别保证而言,甚至ARM处理器也变得更加兼容。 操作系统之间也存在差异,并且这些技术在Linux上比Windows上更有效。 但是,如果您在MacOSX或Windows上进行开发并使用Linux进行生产,则应该没有任何问题。 这就是我们在高频交易中所做的。

我们通过使用堆产生了哪些新问题?

没有什么是免费的,堆外情况就是这样。 堆外的最大问题是您的数据结构变得不太自然。 您或者需要一个可以直接映射到堆外的简单数据结构,或者需要一个序列化和反序列化的复杂数据结构以使其脱离堆。 显然使用序列化有其自身的麻烦和性能损失。 因此,使用序列化要比在堆对象上慢得多。

在金融世界中,最昂贵的数据结构是平坦且简单的,充满了原语,可以很好地从堆中映射出很少的开销。 但是,这并不适用于所有应用程序,您可以获得复杂的嵌套数据结构(例如图形),最终还必须在堆上缓存某些对象。

另一个问题是,JVM限制了您可以使用的系统数量。 您不必担心JVM会使系统过载太多。 有了堆外处理,就解除了一些限制,您可以使用比主内存大得多的数据结构,并且开始担心如果要这样做,您将拥有哪种磁盘子系统。 例如,您不希望分页至具有80 IOPS的HDD,而您可能希望具有80,000 IOPS(每秒输入/输出操作)或更高(即快1000倍)的SSD。

OpenHFT如何提供帮助?

OpenHFT有许多库可以隐藏您实际上正在使用本机内存来存储数据的事实。 这些数据结构是持久的,几乎没有垃圾就可以使用。 这些用于不需少量收集即可全天运行的应用程序中

编年史队列 -持久的事件队列。 支持同一台机器上跨JVM的并发编写器,以及跨机器并发读取器。 微秒级的延迟和每秒数百万条消息的持续吞吐量。

编年史地图 –键值地图的本机或持久存储。 可以在同一台机器上的JVM之间共享,通过UDP或TCP复制和/或通过TCP远程访问。 微秒级延迟和持续的读/写速率,每台机器每秒可进行数百万次操作。

线程亲和性 –将关键线程绑定到隔离的内核或逻辑CPU,以最大程度地减少抖动。 可以将抖动降低1000倍。

使用哪个API?

如果您需要记录每个事件->编年史队列

如果仅需要最新结果作为唯一键->编年史地图

如果您关心20微秒抖动->线程亲和力

结论

堆外内存可能会带来挑战,但也会带来很多好处。 您可以在其中看到最大的收益,并与其他为实现可伸缩性而引入的解决方案进行比较。 与在堆缓存,消息传递解决方案或进程外数据库上使用分区/分片相比,堆外可能更简单,更快。 通过提高速度,您可能会发现不再需要为达到所需性能而需要做的一些技巧。 例如,堆外解决方案可以支持对OS的同步写入,而不必异步执行它们,而会丢失数据。

但是,最大的收获就是启动时间,使您的生产系统重新启动的速度更快。 例如,映射到1 TB数据集中可能需要10毫秒,并且通过重播每个事件以使您每次都获得相同的行为,可以简化测试的可重复性。 这使您可以创建可以依靠的质量体系。

翻译自: https://www.javacodegeeks.com/2014/12/on-heap-vs-off-heap-memory-usage.html

如何分析堆外内存使用情况

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

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

相关文章

centos 虚拟机glibc升级_分享Centos6.5升级glibc过程

上次看到有同学对Centos系统 glibc升级有点疑问, 不过相对来说glibc升级还是比较简单的, 网上也有很多介绍文章, 这里整理了个安装过程供大家参考下 阅读原文场景需求默认的Centos6.5 glibc版本最高为2.12, 而在进行Nodejs开发时项目所依赖的包往往需要更高版本的glibc库支持, …

windows redis批量删除前缀的key_阿里官方Redis开发规范!

本文主要介绍在使用阿里云Redis的开发规范&#xff0c;从下面几个方面进行说明。键值设计命令使用客户端使用相关工具通过本文的介绍可以减少使用Redis过程带来的问题。一、键值设计1、key名设计可读性和可管理性以业务名(或数据库名)为前缀(防止key冲突)&#xff0c;用冒号分隔…

matchers依赖_Hamcrest Matchers的高级创建

matchers依赖介绍 上一次 &#xff0c;我讨论了Hamcrest Matcher是什么&#xff0c;如何使用以及如何制作。 在本文中&#xff0c;我将解释创建Hamcrest Matchers的更多高级步骤。 首先&#xff0c;我将分享如何使您的匹配器更易于类型安全&#xff0c;然后介绍无状态匹配器的一…

深入浅出讲解C语言#define宏定义应用及使用方法

在C语言中&#xff0c;我们使用#define来定义宏。在C程序编译的预处理阶段&#xff0c;预处理器会把宏定义的符号替换成指定的文本。不带参数的宏关于宏最常见的就是用来定义数值常量的名称&#xff0c;即没有参数的宏定义&#xff0c;采用如下形式&#xff1a;1#define 宏名称…

安卓系统双屏异显_Android 双屏异显实现的三种方式

在各种产品脑洞大开的时代&#xff0c;需求也是日益新异&#xff0c;笔者最近开发了一套双屏异显app。现在做一些总结1.双屏异显第一种实现方式(官方提供的Presentation)Android 提供了一个叫 Presentation 类&#xff0c;来实现第二屏&#xff0c; 继承 Presentation 实现第二…

hazelcast入门教程_Hazelcast入门指南第5部分

hazelcast入门教程这是我撰写的有关Hazelcast的一系列文章的延续。 我强烈建议您阅读其他内容&#xff1a; 第1 部分 &#xff0c; 第2 部分 &#xff0c; 第3 部分和第4部分 。 一气呵成的东西 这篇文章中没有Hazelcast专用代码。 让我重复一遍。 这篇文章中没有Hazelcast专用…

单片机C语言编程:.H文件与.C文件的关系!

一个.C文件对应一个.H文件是一种良好的编程习惯&#xff0c;那么.C和.H文件之间的关系是怎么样的呢&#xff1f;一、.H文件与.C文件的关系&#xff1a;迄今为止&#xff0c;写过的程序都是一些很简单的程序&#xff0c;从来没有想到要自己写.H文件&#xff0c;也不知道.H文件到…

python编程快速上手-----让繁琐工作自动化_Python编程快速上手让繁琐工作自动化--逗号代码和字符图网格...

逗号代码假定有下面这样的列表&#xff1a;spam [apples, bananas, tofu, cats]编写一个函数&#xff0c;它以一个列表值作为参数&#xff0c;返回一个字符串。该字符串包含所有表项&#xff0c;表项之间以逗号和空格分隔&#xff0c;并在最后一个表项之前插入and。例如将前面…

spring依赖注入_Spring的依赖注入陷阱

spring依赖注入Spring框架中有三种注入变量&#xff1a; 基于二传手的注射 基于构造函数的注入 基于现场的注入 这些机制中的每一种都有优点和缺点&#xff0c;并且不仅只有一种正确的方法。 例如现场注入&#xff1a; Autowired private FooBean fooBean;在生产代码中使用…

C语言中的“悬空指针”和“野指针”是什么意思?

提起C语言大部分开发者很自然就会想到指针二字&#xff0c;没错&#xff0c;作为C的核心和灵魂&#xff0c;它的地位咱们就不再赘述了&#xff0c;今天我们想跟大家讲的是指针中的两个特有名词&#xff1a;“悬空指针”和“野指针”。1 悬空指针C语言中的指针可以指向一块内存&…

java zip解压_Java语言入门第一课

Java最初的目标是嵌入式设备&#xff0c;不过在嵌入式设备方面并未取得成功。失之东隅&#xff0c;收之桑榆&#xff0c;Java却在Web领域被广泛接受。近年来&#xff0c;随着Java在服务器领域的不断突破&#xff0c;让这门语言越来越流行。有人喜欢Java的纯面向对象&#xff0c…

怎么用c语言做出等妖三角形_初二数学培优,怎么用顶点坐标求三角形面积?割补法这样用很简单...

点击右上角关注“陈老师初中数理化”分享学习经验&#xff0c;一起畅游快乐的学习生活。根据顶点坐标求解三角形的面积是初二数学的重要知识点&#xff0c;本文就例题详细解析这类题型的解题思路&#xff0c;希望能给初二学生的数学学习带来帮助。例题如图&#xff0c;在平面直…

restful xml_使用入站适配器公开HTTP Restful API。 第1部分(XML)

restful xml1.简介 这篇文章的目的是使用Spring Integration HTTP入站适配器实现HTTP Restful API。 本教程分为两个部分&#xff1a; XML配置示例&#xff08;同一篇文章&#xff09;。 Java DSL示例。 这将在本教程的下一部分中进行说明&#xff0c;展示如何使用Spring Int…

C语言的位域

位域是什么&#xff1f;有些数据在存储时并不需要占用一个完整的字节&#xff0c;只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态&#xff0c;用 0 和 1 表示足以&#xff0c;也就是用一个二进位。正是基于这种考虑&#xff0c;C语言又提供了一种叫做位域的…

xp精简工具_办公人士需要精简Win10吗?

首先要说自己的系统需求1&#xff0c;笔记本是主要生产力工具&#xff0c;靠它做方案&#xff0c;联系网络社交&#xff1b;2&#xff0c;会偶尔&#xff08;一月2-3次&#xff09;用到PS&#xff0c;AI&#xff0c;PR等软件&#xff1b;3&#xff0c;文件多&#xff0c;版本多…

matlab 删除路径_MATLAB使用教程(一)—新手来看

前言&#xff1a;在这里&#xff0c;本人默认大家已经安装好了MATLAB软件&#xff0c;如果没有&#xff0c;请自行安装。注意事项&#xff1a;新手容易犯错&#xff0c;打开MATLAB之后&#xff0c;请按CTRLQ这个组合键&#xff0c;是不是发现你的MATLAB关闭了&#xff1f;对&am…

数据的gzip压缩解压缩_使用GZIP和压缩数据

数据的gzip压缩解压缩抽象 我们都知道用zip或gzip压缩文件的含义。 但是在Java中使用压缩文件并不像您想的那样简单&#xff0c;特别是如果您不是直接使用文件而是压缩流数据时。 我们会去&#xff1a; 如何将字符串转换为压缩/压缩字节数组&#xff0c;反之亦然 创建用于读取…

C语言开发单片机为啥都是全局变量形式?

01前言全局变量简直就是嵌入式系统的戈兰高地。冲突最激烈的双方是&#xff1a;1. 做控制的工程师&#xff1b;2. 做非嵌入式的软件工程师。02做控制的工程师特点他们普遍的理解就是“变量都写成全局该有多方便”。我之前面试过一个非常有名的做控制实验室里出来的PhD/Master&a…

ajax get请求_python测试开发django50.jquery发送Ajax请求(get)

前言有时候&#xff0c;我们希望点击页面上的某个按钮后&#xff0c;不刷新整个页面&#xff0c;给后台发送一个请求过去&#xff0c;请求到数据后填充到html上&#xff0c;这意味着可以在不重新加载整个网页的情况下&#xff0c;对网页的某部分进行更新。Ajax可以完美的实现。…

primefaces_PrimeFaces Mobile入门

primefaces介绍 如果您已经开发了利用PrimeFaces的应用程序&#xff0c;或者打算开发可在台式机和移动设备上使用的Web应用程序&#xff0c;请考虑将PrimeFaces Mobile用于您的移动实施。 这篇博客文章将介绍一些基础知识&#xff0c;以帮助您开始为现有的PrimeFaces应用程序开…