I have a Java 3D program which uses lots (hundreds) of 3D models (3ds and obj).
The more models I use (and I really, really have to, it's kind of 3D model of the real world object) the more heavier the program becomes, till the point when any single operation takes ages to complete.
CPU consumption rarely reaches 50%, mostly is moving between 10%-30%, but memory consumption is growing (obviously) with each added 3D model.
I know how to minimize memory imprint of c++/ c programs, but with Java's GC is there anything I can do about it except increasing the JVM's memory with -Xmx? I am already running with -xMx512Mb.
I have checked GC logs, using GCViewer, didn't find anything suspicious.
I am aware of some very similar questions on SO, but none answered my question exactly.
My IDE is IntelliJ 11.
There are two simple ways to decrease the number of objects you are creating, and one or both of them may work for your purposes, though without specifications I can't be sure.
1) Work with highly mutable objects. If you need to simulate a large number of things with a great deal of similarity, but which don't have to interact with each other (for example, a hundred thousand simulations of a dozen particles interacting, with slightly different particles each time), then using the same dozen or so objects over and over, and making use of mutator functions to transfer the burden to the CPU. However, I doubt that using many objects in sequence is a problem for you, given that Java already has built-in garbage collection.
2) Make the similarities between similar objects their own class. For example, if you have the need for a lot of objects, and you notice that a significant proportion of them share a number of memory-intensive characteristics, store those characteristics in their own class and refer to a single instance of that class in every object with the exact same field values. As an example, consider a set of Apple objects. You could either create different classes for GrannySmithApples, MackintoshApples, RedDeliciousApples with their own static fields for characteristics shared across the class (e.g. RedDeliciousApples have a static String field declared in the abstract class Apple and set to "red"), or (to allow more flexibility at runtime) each class could have an instance of CoreCharacteristic. If multiple objects share the same core characteristics, the code:
CoreCharacteristic c = new CoreCharacteristic(<some parameters>);
Apple apple1 = new Apple(c);
Apple apple2 = new Apple(c);
Apple apple3 = new Apple(c);
Apple apple4 = new Apple(c);
will use only one CoreCharacteristic for all four apples, quartering the amount of memory needed to store the fields of CoreCharacteristic which would have otherwise been replicated for each Apple.
There are two different approaches I can think of to handle your issues:
Control when the GC kicks in: here is a full article describing how to control the garbage collector and the different algorithms used to clean up the memory. I found this approach very useful when an application is creating thousands and thousands of DTOs in a minute.
If your application is not creating too many objects that are trashed quickly then I suggest you have a look at your model and improve its efficiency. Remember that when dealing with 3D visualization, all what matters is how you structure your scene graph.
On a side note, 3D visualization does not take that much CPU when using OpenGL based solutions. This is mainly due to the fact that it is the GPU that gets involved a lot when rendering the scene graph, not the CPU.
From my point of view you have two options:
decrease creating new objects by making them immutable, and reuse of them if they not vary
use flywieght pattern - reuse created objects and work with setters on them, in place of creating new ones again and again - here is great example of implementation that may exaclty suit your needs http://www.javacamp.org/designPattern/flyweight.html - it's about creating color circles. Without flywieght it took 2,5x longer, and memory consumption was ~200 larger. Try it.
Related
I understand it might be hard to answer this question without knowing the details of the problem but I hope some one have encountered a similar situation before and could help me.
I am writing a simulator in Java and I have n neurons that communicate to each other during the simulation time. Each of these neurons have specific parameters and properties and I need to access and maybe manipulate their values during the simulation time.
I am wondering which of the following is the "right" choice:
Storing information in 1-D and 2-D arraylists - this means a lot of look ups and requires extra care to make sure information are linked properly.
Having one class with fields and methods required for a neuron and making different instances of it for every neuron (using the constructor to provide parameters specific to that neuron).
Basically, my question is where is the limit for making instances of a class? When does it become too many and inefficient? 100s? 1000s?
Let me know if I should explain more.
Appreciate any other suggestion as well.
Thank you.
Only memory is a limit for making instances of a class, there are no other performance related issues with having many instances of classes(*).
However, class instances do have some additional information stored with them so they come with more memory overhead than using arrays. For each instance of a class you can expect 16 bytes of overhead.
(*) In theory anyway, in practice you may encounter more GC overhead or have worse performance due to cache misses if the instances are not spread favorably in memory vs the array solution.
I am writing a game for android, and I am worry about performance and memory.
Is Java less effective with many classes?
Many classes affect performance?
I don't think so. Only one thing would be at startup it will be little slow (negligible) to load all classes to memory (Which is optimized with newer versions).
Its not so much the classes that you have to worry about. Much rather it depends on the number of Objects that you instantiate and the frequency with witch they are dereferenced and hence have to be cleaned up by the GC.
So if anything keep an eye on the number of Objects beeing created and dereferenced.
Back in J2ME days, where some devices had a limit of 64k jar (for example) - usage of lots of classes affected the jar size, and one of the tricks was to reduce number of classes.
The only overhead you will have is class loading of each one of these classes.
Not sure if this happens on startup or during first access/allocation to object of a given class (or combination of both in some manner), but this is truly not an issue.
The number of classes is practically irrelevant when it comes to performance. Generally there are many other areas that usually have much greater impact on perceived performance (we are talking about magnitudes here, not a few percent).
It also depends of what you consider many classes. I would consider >30K classes many (I worked in a project that had this many classes), but you probably already consider 1K classes many (and 1K is nothing, really). Usually the only notable effect of adding another 10K classes (that are also used, mind that classes not loaded do not measurably affect performance) is to add a few more seconds of startup time.
Focus on correct function first, worry about performance when you achieved that. The only performance consideration you should have while working on function is the choice of suitable data structures and algorytms. Chosing proper data structures and efficent algorytms has far greater impact than shaving off a fraction of a percent in the area of class loading.
I am a bit new to profiling applications for improving performance. I have selected YourKit as my profiler. There is no doubt that YourKit provides very interesting statistics. Where I am getting stuck is what to do with these statistics.
For instance, Consider a method that operates on a JAXB POJO. The method iterates through the POJO to access a tag/element that is deeply nested inside the XML. This requires 4 layers of for loops to get to the element/tag as shown below :
List<Bundle> bundles = null;
List<Item> items = null;
for(Info info : data) {
bundles = info.getBundles();
for(Bundle bundle : bundles) {
items = bundle.getItems();
//.. more loops like this till we get to the required element
}
}
YourKit tells me that the above code is a 'hot-spot' and 80 objects are getting garbage collected for each call to the method containing this code. The above code is just an example and not the only part where I am getting stuck. Most of the times I have no clue about what to do with the information given by the profiler. What can I possibly do to reduce the number of temporary objects in the above code? Are there any well defined principles for imporoving the performance of an application? What statistics to look for when profiling an application and what implications does each kind of statistics have?
Edit :
The main objective for profiling the application is to increase the throughput and response time. The current throughput is only 10 percent of the required throughput!
Focus on the statistics relevant to your performance goal. You are interested in minimal response time, so look at how much each method contributes to response time, and focus on those that contribute much (for single threaded processing, that's simply elapsed time during method call, summed over all invocation of that method). I am not sure what YourKit defines as hot spots (check the docs), but it's probably the methods with highest cummulative elapsed time, so hot spots are a good thing to look at. In constrast, object allocation has no direct impact on response time, and is irrelavant in your case (unless you have identified that the garbage collector contributes a significant proportion of cpu time, which it usually doesn't).
I absolutely agree with the given answers.
I would like to add that considering your concrete example, you actually can make an improvement by using xpath api to access the specific location in the XML.
In situations where you don't need to actually iterate the entire DOM, this should be your first choice since it is declarative and hence more expressive and less error prone.
It would often give you superior performance as well (For very complex queries it may not be the case, but you seem to have a simple scenario).
A way to improve the loop would be to change your schema and essentially flatten the model, of course this depends on whether you can change the schema. This way the generated Java will not require 4 layers of looping. Of course at the end of the day you need to ask yourself is the code really a problem - 80 objects are getting GCed so? Is your application running slow? Are you experiencing memory issues? Remember premature optimization is the root of all evil!
Profiling and optimization is a complex beast and depends on may things (Java version, 32 vs 64 bit os, etc...). Furthermore the optimization might not always require code changes, for example you could resolve problems by changing your GC policy on the JVM - for example there are GC policies that are more effective in situations where your code is creating many small objects that need to be GCed frequently. If you had specifics maybe it would be easier to help you however your question seems too broad. In fact there are many books written on topic which might be worth a read.
Whenever I write a new class, I use quite a ton of class variables to describe the class's properties, up to the point where when I go back to review the codes I've typed, I see 40s to 50s of class variables, regardless of whether they are public, protected, or private, they are all used prominently throughout the classes I've defined.
Even though, the class variables consists of mostly primitive variables, like booleans, integers, doubles, etc., I still have this uneasy feeling where that some of my classes with large amounts of class variables may have an impact on performances, however negligible they may be.
But being rational as possible, if I consider unlimited RAM size and unlimited Java class variables, a Java class may be an infinitely large block of memory in the RAM, which the first portion of the block contains the class variables partitions, and the rest of the block contains the addresses to the class methods within the Java class. With this amount of RAM, the performance for it is very nontrivial.
But that above isn't making my feelings any easier than said. If we were to consider limited RAM but unlimited Java class variables, what would be the result? What would really happen in an environment where performance matters?
And probably may get mentioned beforehand, I don't know if having lots of class variables counts as bad Java practice, when all of them are important, and all classes have been refactored.
Thanks in advance.
Performance has nothing to do with the number of fields an object has. Memory consumption is of course potentially affected, but if the variables are needed, you can't do much about it.
Don't worry too much about performance. Make your code simple, readable, maintainable, tested. Then, if you notice performance problems, measure and profile to see where they come from, and optimize where needed.
Maintainability and readability is affected by the number of fields an object has though. 40 to 50 fields is quite a lot of fields, and is probably an indication that your classes do too much on their own, and have too many responsibilities. Refactoring them to many, smaller subclasses, and using composition would probably be a good idea.
I hope I don't sound like an ass, but in my view having more than 10 properties in a class is usually a hint of a bad design and requires justification.
Performance wise, if you very often need all those properties, then you're going to be saving some memory, as each object also has a header. So intead of having 5-10 classes you put everyting into one and you save some bytes.
Depending on which garbage collector you use, having bigger objects can be more expensive to allocate (this is true for the CMS garbage collector, but not for the parallel one). More GC work = less time for your app to run.
Unless you're writing a high traffic, low latency application, the benefits of having less classes (and using less memory) is going to be completely overwhelmed by the extra effort needed for maintenance.
The biggest problem I see in having a class with a lot of variables is Thread safety - it is going to be really hard to reason about the invariants in such a case. Also reading/maintaining such a class is going to be really hard.
Of course if you make as much as you can fields immutable, that is going to be a lot better.
I try to go with : less is better, easier to maintain.
A basic principle we are always taught is to keep cohesion high (one class is focusing on one task) and coupling low (less interdependency among classes so that changes in one doesnot effect others).
While designing a system, I will believe the focus should be more on maintainable design, performance will take care of itself. I don't think there is fixed limit on number of variables a class can have as a good practice, as this will strictly depend on your requirement.
For example, if I have a requirement where the application suggest a course to student, and algorithm needs 50 inputs (scores, hobbies etc), it will not matter whether this data is available in one class or multiple, as the whole information needs to be loaded in the RAM for a faster execution.
I will again say, take care of your design, it is both harmful to keep unnecessary variables in a class (as it will load non-required information to RAM) or split into more classes than required (more references and hence pointer movement)
1. I always use this as a thumb of rule. A Class should have only One reason to Change, so It should Do only One Thing.
2. Keeping this in mind i take those variables which are needed to define this class's attributes.
3. I make sure that my class is following the Cohesive principle, where the Methods within the class reflects the Class name.
4. Now after sorting everything out, if i need some other variables to work-out my class, then i need to use them, i have no choice...Moreover after all these thinking and work going into creating a class, will be hardly effected by some additional variables.
Sometimes class variables are used as static final constants to store some default strings like product name, version, OS version, etc. Or even to store product specific settings like font size, type, etc. Those static variables can be kept at class level.
You can also use HashMap instead of simple class if you just want to store fields constants or like product setting that rarely change. That may help you speed you response time.
Two things I would like to mention :
1. All instance variables are stored in Heap area of RAM..
2. All static variables are stored in non Heap area(Method area to be specific).
Whatever be the type of variable(instance or static), ultimately all reside in RAM.
Now coming to your question. As far as instance variable is concerned, java's built-in Garbage collector will work, in most cases well and truly effectively, to keep freeing memory. However, static variables are not garbage collected.
If you are highly concerned with memory issues due to large number of variables in your class, you can resort to using Weak References instead of traditional strong reference.
I keep wondering about this to try to improve performance and size of my Flex swfs, how do classes vs. static methods vs. instance methods impact performance and the final compiled "executable's" size? Thinking how it might be possible to apply something like HAML and Sass to Flex...
Say I am building a very large admin interface with lots of components and views, and each of those components has a Skin object applied to them (thinking of the Spark Skinning Architecture for Flex).
Now I want to add 10 different Effects to every skin (say there are 100 components on the screen, so that's 1000 instantiated effects). Is it better to:
Have each Effect be a Class (BlurEffect, GlowEffect...), and add those 10 to the skin.
Have all Effects be instance methods in one larger class, say "MultiEffect.as", and add that one class to the skin, referenced like multiEffect.glow().
Have all Effects be static methods in one singleton-esque "EffectManager.as" class, and just reference the effects in the skin via EffectManager.glow(this).
So
Multiple Effect Classes per skin, vs.
One Effect class per skin, with instance methods, vs.
One Effect class globally, with static methods
How do those things impact memory and executable size (swf size in this example)? I know that classes are better OO practices and that static methods are slower than instance methods, and that Singletons are to be avoided, so it's not about performance necessarily. More about memory (which if smaller would be better in some cases), and file size.
Couldn't find such information for Flex, but for Java (which shouldn't be too different), object creation overhead is only 8 bytes of memory.
That means if we're talking about 1000 instances, the overhead of using objects for each instance is at most 8K - negligible. If 100x more, it's still 800K which is still nothing.
So, echoing the previous answers, choose the option that gives you a better design.
Oh, and the difference in resulting file size is pretty much nothing.