本文介绍了如何在Java中记忆配置文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我还在学习Java的绳索,如果对此有明显的答案,那就很抱歉。我有一个占用大量内存的程序,我想找到一种方法来减少它的使用量,但在阅读了很多SO问题后,我认为在开始优化之前我需要证明问题所在。 所以这就是我所做的,我在程序开始时添加了一个断点并运行它,然后我启动了visualVM并让它描述了内存(我也做了同样的事情) netbeans中的东西只是为了比较结果而且它们是相同的)。我的问题是我不知道如何阅读它们,我得到的最高区域只是说 char [] 而且我看不到任何代码或任何东西(这是有意义的)因为visualvm连接到jvm并且无法看到我的源代码,但是netbeans也没有像执行cpu profiling那样向我显示源代码。) 基本上是什么我想知道哪个变量(希望更多的细节,比如在哪种方法中)所有的内存都被使用,所以我可以专注于那里的工作。有一个简单的方法来做到这一点?我现在正在使用eclipse和java进行开发(并且专门为分析安装了visualVM和netbeans,但我愿意安装其他任何你认为可以完成这项工作的东西)。 编辑:理想情况下,我正在寻找能够获取所有物体并按尺寸排序的东西(所以我可以看到哪一个占用内存)。目前它返回诸如string []或int []之类的通用信息,但我想知道它所指的是哪个对象,所以我可以努力使其大小更加优化。解决方案 字符串有问题 基本上在Java中,字符串引用(在幕后使用 char [] 的东西)将主导大多数业务应用程序内存。它们的创建方式决定了它们在JVM中消耗了多少内存。 仅仅因为它们对于大多数业务应用程序来说是如此基本的数据类型,并且它们是其中之一大多数记忆力也很饥渴。这不只是一个Java的东西, String 数据类型在几乎所有语言和运行时库中占用大量内存,因为至少它们只是1的数组每个字符的字节数或更差的字节(Unicode)它们是每个字符多个字节的数组。 在分析具有Oracle JDBC依赖性的Web应用程序上的CPU使用情况时我发现 StringBuffer.append()在所有其他方法调用组合上比CPU周期多了几个数量级,更不用说任何其他方法了呼叫。 JDBC驱动程序执行了大量的 String 操作,对于所有内容使用 PreparedStatements 进行权衡。 你关心的是你无法控制,不是直接控制 什么你应该关注的是你控制中的内容,它确保你不会持续超过你需要的引用,并且你不会不必要地复制内容。 Java中的垃圾收集例程已经过高度优化,如果您了解它们的算法是如何工作的,您可以确保您的程序以这些算法的最佳工作方式运行。 Java堆内存不像其他语言的手动管理内存,这些规则不适用 什么是内存其他语言中的泄漏与Java及其垃圾收集系统不一样/根本原因。 Java内存中很可能没有消耗由一个泄漏的单个超级对象(在其他环境中悬挂引用)。 由于 StringBuffer / StringBuilder 对象在第一个即时版中的大小不合适,然后必须自动增长 char [] 数组以保存后续 append()电话。 由于垃圾收集器所处的范围以及许多其他可能在运行时发生变化的事情,这些中间对象可能会被垃圾收集器保留的时间超过预期。 示例:垃圾收集器可能会确定有候选者,但因为它认为仍有大量内存可能存在在那个时间段将它们冲出来的时间过于昂贵,它会等到内存压力升高。 垃圾收集器现在真的很好,但它不是不可思议,如果你正在做堕落的事情,它会导致它不能最佳地发挥作用。所有JVM版本的垃圾收集器设置都有很多关于互联网的文档。 这些未引用的对象可能还没有达到垃圾收集器认为它需要它们才能从内存中清除它们,或者可能有一些其他对象( List )对它们的引用,例如你没有意识到仍然指向那个对象。这就是Java中最常被称为 leak 的东西,更具体地说是一个参考泄漏。 示例:如果您知道需要使用 StringBuilder构建4K String 使用 new StringBuilder(4096); 不是默认值,就像是32,会立即开始创建垃圾,可以代表你认为对象应该是大小的多倍。 您可以发现使用VisualVM实例化了多少类型的对象,这将告诉您需要了解的内容。不会有一个大闪烁指示单个类的单个实例说这是大内存消费者!,除非只有一个的实例char [] 你正在阅读一些大量文件,这也是不可能的,因为很多其他类在内部使用 char [] ;然后你几乎已经知道了。 我没有看到任何提及 OutOfMemoryError 你的代码中可能没有问题,垃圾收集系统可能没有受到足够的压力来启动和解除分配对象你认为应该清理它。什么你认为是一个问题可能不是,除非你的程序崩溃与 OutOfMemoryError 。这不是C,C ++,Objective-C或任何其他手动内存管理语言/运行时。你不能在你期望的细节层面上决定你的内存是什么。 I'm still learning the ropes of Java so sorry if there's a obvious answer to this. I have a program that is taking a ton of memory and I want to figure a way to reduce its usage, but after reading many SO questions I have the idea that I need to prove where the problem is before I start optimizing it.So here's what I did, I added a break point to the start of my program and ran it, then I started visualVM and had it profile the memory(I also did the same thing in netbeans just to compare the results and they are the same). My problem is I don't know how to read them, I got the highest area just saying char[] and I can't see any code or anything(which makes sense because visualvm is connecting to the jvm and can't see my source, but netbeans also does not show me the source as it does when doing cpu profiling).Basically what I want to know is which variable(and hopefully more details like in which method) all the memory is being used so I can focus on working there. Is there a easy way to do this? I right now I am using eclipse and java to develop(and installed visualVM and netbeans specifically for profiling but am willing to install anything else that you feel gets this job done).EDIT: Ideally, I'm looking for something that will take all my objects and sort them by size(so I can see which one is hogging memory). Currently it returns generic information such as string[] or int[] but I want to know which object its referring to so I can work on getting its size more optimized. 解决方案 Strings are problematicBasically in Java, String references ( things that use char[] behind the scenes ) will dominate most business applications memory wise. How they are created determines how much memory they consume in the JVM.Just because they are so fundamental to most business applications as a data type, and they are one of the most memory hungry as well. This isn't just a Java thing, String data types take up lots of memory in pretty much every language and run time library, because at the least they are just arrays of 1 byte per character or at the worse ( Unicode ) they are arrays of multiple bytes per character.Once when profiling CPU usage on a web app that also had an Oracle JDBC dependency I discovered that StringBuffer.append() dominated the CPU cycles by many orders of magnitude over all other method calls combined, much less any other single method call. The JDBC driver did lots and lots of String manipulation, kind of the trade off of using PreparedStatements for everything.What you are concerned about you can't control, not directly anywayWhat you should focus on is what in in your control, which is making sure you don't hold on to references longer than you need to, and that you are not duplicating things unnecessarily. The garbage collection routines in Java are highly optimized, and if you learn how their algorithms work, you can make sure your program behaves in the optimal way for those algorithms to work.Java Heap Memory isn't like manually managed memory in other languages, those rules don't applyWhat are considered memory leaks in other languages aren't the same thing/root cause as in Java with its garbage collection system.Most likely in Java memory isn't consumed by one single uber-object that is leaking ( dangling reference in other environments ).It is most likely lots of smaller allocations because of StringBuffer/StringBuilder objects not sized appropriately on first instantantations and then having to automatically grow the char[] arrays to hold subsequent append() calls.These intermediate objects may be held around longer than expected by the garbage collector because of the scope they are in and lots of other things that can vary at run time.EXAMPLE: the garbage collector may decide that there are candidates, but because it considers that there is plenty of memory still to be had that it might be too expensive time wise to flush them out at that point in time, and it will wait until memory pressure gets higher.The garbage collector is really good now, but it isn't magic, if you are doing degenerate things, it will cause it to not work optimally. There is lots of documentation on the internet about the garbage collector settings for all the versions of the JVMs.These un-referenced objects may just have not reached the time that the garbage collector thinks it needs them to for them to be expunged from memory, or there could be references to them held by some other object ( List ) for example that you don't realize still points to that object. This is what is most commonly referred to as a leak in Java, which is a reference leak more specifically.EXAMPLE: If you know you need to build a 4K String using a StringBuilder create it with new StringBuilder(4096); not the default, which is like 32 and will immediately start creating garbage that can represent many times what you think the object should be size wise.You can discover how many of what types of objects are instantiated with VisualVM, this will tell you what you need to know. There isn't going to be one big flashing light that points at a single instance of a single class that says, "This is the big memory consumer!", that is unless there is only one instance of some char[] that you are reading some massive file into, and this is not possible either, because lots of other classes use char[] internally; and then you pretty much knew that already.I don't see any mention of OutOfMemoryErrorYou probably don't have a problem in your code, the garbage collection system just might not be getting put under enough pressure to kick in and deallocate objects that you think it should be cleaning up. What you think is a problem probably isn't, not unless your program is crashing with OutOfMemoryError. This isn't C, C++, Objective-C, or any other manual memory management language / runtime. You don't get to decide what is in memory or not at the detail level you are expecting you should be able to. 这篇关于如何在Java中记忆配置文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-19 02:41