如何在Java中记忆配置文件?

Err*_*404 34 java profiling visualvm

我还在学习Java的绳索,如果对此有明显的答案,那就很抱歉.我有一个占用大量内存的程序,我想找到一种方法来减少它的使用,但在阅读了很多SO问题后,我认为我需要在开始优化之前证明问题出在哪里.

所以这就是我所做的,我在程序开始时添加了一个断点并运行它,然后我启动了visualVM并让它描述了内存(我也在netbeans中做同样的事情只是为了比较结果而且它们是相同的).我的问题是我不知道如何阅读它们,我得到的最高区域只是说char[],我看不到任何代码或任何东西(这是有道理的,因为visualvm连接到jvm并且看不到我的来源,但是netbeans也没有向我显示源代码,因为它在执行cpu profiling时也是如此.

基本上我想知道的是哪个变量(希望更多的细节,比如在哪种方法中)所有的内存都在使用,所以我可以专注于在那里工作.有一个简单的方法来做到这一点?我现在正在使用eclipse和java进行开发(并且专门为分析安装了visualVM和netbeans,但是我愿意安装其他任何你认为完成这项工作的东西).

编辑:理想情况下,我正在寻找将我的所有对象和大小排序的东西(所以我可以看到哪一个占用内存).目前它返回诸如string []或int []之类的通用信息,但我想知道它所指的是哪个对象,所以我可以努力使其大小更加优化.

小智 24

字符串是有问题的

基本上在Java中,String引用(char[]在幕后使用的东西)将在大多数业务应用程序中占据主导地位.它们的创建方式决定了它们在JVM中消耗了多少内存.

仅仅因为它们对于大多数业务应用程序来说是如此基本的数据类型,并且它们也是最需要内存的应用程序之一.这不仅仅是Java的东西,String数据类型占用了几乎所有语言和运行时库的大量内存,因为至少它们只是每个字符1个字节的数组,或者更糟(Unicode)它们是数组每个字符多个字节.

一旦在同样具有Oracle JDBC依赖性的Web应用程序上分析CPU使用情况时,我发现StringBuffer.append()在所有其他方法调用组合中,CPU周期占据了多个数量级,而不是任何其他单个方法调用.JDBC驱动程序做了很多很多的String操作,有点PreparedStatements用于一切的权衡.

你关心的是你无法控制,而不是直接控制

您应该关注的是控制中的内容,即确保您不会持续超过您需要的引用,并且您不会不必要地复制内容.Java中的垃圾收集例程已经过高度优化,如果您了解它们的算法是如何工作的,您可以确保您的程序以最佳方式运行,以使这些算法工作.

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

在其他语言中被认为是内存泄漏与Java及其垃圾收集系统不同的原因/根本原因.

Java内存中很可能不会被泄漏的单个超级对象(在其他环境中悬挂引用)消耗掉.

很可能是很多较小的分配,因为StringBuffer/ StringBuilder对象在第一个瞬时没有适当地调整大小,然后必须自动增长char[]数组以保存后续append()调用.

由于垃圾收集器所处的范围以及许多其他可能在运行时变化的事物,这些中间对象可能会被垃圾收集器保持的时间长于预期.

示例:垃圾收集器可能会确定存在候选者,但是因为它认为仍有大量内存需要在那个时间段将它们清除出来并且它会花费太多时间,并且它会等到内存压力越来越大.

垃圾收集器现在真的很好,但它不是魔术,如果你做退化的事情,它将导致它不能最佳地工作.互联网上有很多关于所有JVM版本的垃圾收集器设置的文档.

这些未引用的对象可能还没有达到垃圾收集器认为需要它们从内存中清除它们的时间,或者可能存在由其他某个对象(List)保存的引用,例如您没有意识到仍然指向那个对象.这是Java中最常被称为泄漏的泄漏,更具体地说是参考泄漏.

示例:如果您知道需要String使用StringBuilder创建4K 来创建4K 而new StringBuilder(4096);不是默认值,这就像32并且将立即开始创建垃圾,这可以表示您认为对象应该是大小明智的很多倍.

您可以发现使用VisualVM实例化了多少类型的对象,这将告诉您需要了解的内容.没有一个闪烁的大灯指向单个类的单个实例,它说"这是大内存消费者!",除非只有一个实例char[],你正在阅读一些file into,这也是不可能的,因为很多其他类在char[]内部使用; 然后你几乎已经知道了.

我没有看到任何提及 OutOfMemoryError

您的代码中可能没有问题,垃圾收集系统可能没有足够的压力来启动和释放您认为应该清理的对象.什么,你认为是一个问题可能不大,除非没有你的程序与崩溃OutOfMemoryError.这不是C,C++,Objective-C或任何其他手动内存管理语言/运行时.你无法在你期望的细节层面上决定你的内存是什么.


Ing*_*gel 10

JProfiler中,您可以转到堆walker并激活最大的对象视图.您将看到保留最多内存的对象."保留"内存是如果删除了对象,垃圾收集器将释放的内存.

然后,您可以打开对象节点以查看保留对象的引用树.这是最大的对象视图的屏幕截图:

在此输入图像描述

免责声明:我公司开发JProfiler