java - 如何在Java中存储配置文件?

标签 java profiling visualvm

我仍在学习Java的绳索,如果对此有明确的答案,对不起。我有一个占用大量内存的程序,我想找到一种减少其使用量的方法,但是在阅读了许多SO问题之后,我认为我需要在开始优化之前证明问题出在哪里。

所以这就是我做的事情,我在程序的开始处添加了一个断点并运行它,然后启动visualVM并对其进行了内存配置(我在netbeans中也做了同样的事情,只是为了比较结果,它们是相同的)。我的问题是我不知道该如何阅读它们,我只说了char[]就得到了最高的区域,我看不到任何代码或任何内容(这是有道理的,因为visualvm正在连接到jvm并且看不到我的源代码,但是netbeans也没有像执行cpu分析时那样显​​示源代码。

基本上我想知道的是所有内存都在使用哪个变量(以及希望有更多详细信息,例如哪种方法),因此我可以专注于在那里工作。有没有简单的方法可以做到这一点?我现在正在使用eclipse和java进行开发(并安装了专门用于性能分析的visualVM和netbeans,但愿意安装您认为可以完成这项工作的任何其他工具)。

编辑:理想情况下,我正在寻找一种可以容纳所有对象并按大小对它们进行排序的东西(这样我就可以看到哪一个正在占用内存)。当前,它返回通用信息,例如string []或int [],但我想知道其引用的对象,因此我可以使它的大小更优化。

最佳答案

字符串有问题

基本上在Java中,String引用(在幕后使用char[]的事物)将主导大多数业务应用程序的明智存储。如何创建它们决定了它们在JVM中消耗了多少内存。

仅仅因为它们对于大多数业务应用程序来说是非常重要的数据类型,并且它们也是最需要消耗内存的一种。这不仅仅是Java的事情,String数据类型几乎在每种语言和运行时库中都占用大量内存,因为至少它们是每个字符1个字节的数组,或者更糟的是,它们是(Unicode)数组每个字符多个字节。

有一次在对还具有Oracle JDBC依赖性的Web应用程序上的CPU使用情况进行性能分析时,我发现StringBuffer.append()比所有其他方法调用主导了CPU周期许多数量级,而与其他任何单个方法调用相比却少得多。 JDBC驱动程序进行了很多String操作,这是对所有内容都使用PreparedStatements的一种折衷。

您担心的是您无法控制的,总之不是

您应该关注的是控件中的内容,这可确保您保留的引用的时间不超过所需的时间,并且不会不必要地重复操作。 Java中的垃圾回收例程已高度优化,如果您了解它们的算法如何工作,则可以确保程序以最佳方式运行,以使这些算法起作用。

Java堆内存与其他语言的手动管理的内存不同,这些规则不适用于

在其他语言中,所谓的内存泄漏与Java及其垃圾回收系统的原因/根本原因不同。

Java内存中最有可能不会被泄漏的单个 super 对象占用(在其他环境中悬空引用)。

由于StringBuffer/StringBuilder对象在首次实例化时大小不正确,然后不得不自动增长char[]数组以容纳后续的append()调用,因此很有可能是较小的分配。

这些中间对象的保留时间可能比垃圾收集器所期望的保留时间长,这是因为它们所处的范围以及运行时可能发生变化的许多其他事物。

示例:,垃圾收集器可能会确定有候选对象,但是因为它认为仍然有足够的内存,以至于在那个时间点将它们清除掉可能是太昂贵的时间,所以它将等待直到内存压力变高。

垃圾收集器现在确实非常好,但是并不是魔术,如果您正在执行退化的事情,它将导致它无法最佳工作。互联网上有很多关于所有版本JVM的垃圾收集器设置的文档。

这些未引用的对象可能还没有达到垃圾回收器认为将它们从内存中删除所需的时间,或者可能有其他对象(List)持有的对它们的引用,例如,您没有意识到仍然指向那个对象。这是Java中最常见的泄漏,更具体地说是引用泄漏。

示例:如果您知道需要使用String来构建4K StringBuilder,请使用new StringBuilder(4096);(不是默认值)创建它,例如32,它将立即开始创建垃圾,垃圾可以代表您认为该对象在大小上明智的很多倍。

您可以发现用VisualVM实例化了多少种对象类型,这将告诉您您需要了解的内容。不会有一个大的指示灯指向一个类的单个实例,即“这是大内存消耗者!”,也就是说除非您正在读取一些char[]的实例,将大量文件放入其中,这也是不可能的,因为许多其他类在内部使用char[];然后您几乎已经知道了。

我看不到OutOfMemoryError

您的代码可能没有问题,垃圾回收系统可能没有承受足够的压力来启动和释放您认为应该清除的对象。您认为是什么问题的可能不是问题,除非您的程序因OutOfMemoryError而崩溃。这不是C,C++,Objective-C或任何其他手动内存管理语言/运行时。您无法在期望的详细级别上决定内存中的内容与否。

关于java - 如何在Java中存储配置文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10108942/

相关文章:

java - 使用字符串、变量、循环的正确编码实践 - Java (Android)

java - 我怎么知道正则表达式是否有多个可能的匹配项?

java - Spring AntRequestMatcher 不匹配

java - 来自 Web ui 的 Spring 批处理作业?

c - 监视 linux 内核中上下文切换次数的最有效方法是什么?

java - 衡量 Java 程序内存使用情况的最佳方法?

java - 分析 Java 应用程序 : Cumulative times for methods recursively

Go Profiler (pprof) 时间差异

java - 我可以将 hprof/jmap 转储与 VisualVM 进行比较吗?

java - 使用 VisualVM 在 AIX 上分析 Java 进程