Higher memory consumption in Java 8 than Java 7 - java

I'm developing a JavaFX desktop application using Java 7. The application I'm developing uses 10-12 background threads which gets system information or makes HTTP request. I also use some JNA and JNI code.
When i limit the heap size to 40 MB, it's fairly enough and the application runs without a problem with total ~100 MB memory.
However since Oracle is dropping support for Java 7 in April, I decided to upgrade the application to Java 8, the upgrade went smoothly, not much code change required, but i noticed the total memory consumption increased to 130+-20 MB. I researched about this problem, and found out Java 8 introduced Metaspace, I think that may be the problem, but in Java 7 I never set the PermGenSize so in the end I have no idea why the application uses more memory.
Just so you know Metaspace usage is about 33-36 MB in VisualVM.
Any help would be appreciated , thanks
-------SOLVED---------
The problem was; the JDK I was using was 64 bit, since 64 bit JDK on Windows only contains server mode, I installed a 32 bit JDK 8 and started using it in client mode, since then the RAM usage is about 80 MB.

Related

Java JVM Heap Size

I have an application that on launch requests a specific amount of RAM using the following command.
java -Xms512m -Xmx985m -jar someJarfile.jar
This command fails to run on my computer with 8.0GB of RAM because it can not create an object heap of the specified size. If I lower the max range to something below 700MB it works fine.
What is even stranger is that even doing a simple java -Xmx768m -version fails when the -Xmx flag value exceeds 700m. I am trying to run it with Java 1.7Uu67 32-bit(that is what the jar was built with) and even newer versions of Java 1.7 and event Java 1.8. I would understand if the max heap was higher and I was using 32bit, but it is not above the ~1.4GB cap of 32-bit java
Is there a configuration parameter that I am missing somewhere that would be causing this, some sort of software that may be interfering? It does not make sense to me as to why I can not allocate 700MB of RAM on a machine with 8.0GB of RAM. I
I should also note that there are no other processes running that are taking up all of my RAM. It is a fresh install of Windows 7.
While 700 MB is pretty low, it is not surprising.
The 32-bit Windows XP emulator in Windows works the same way as Windows XP with all it's limitations. It means you lose 2 GB or a potential 4 GB to the OS. This means programs already running use up virtual memory space. Also if your program uses shared libraries or off heap storage like direct memory and memory mapped files this will means you lose virtual memory for the heap. Effectively you are limited to 1.4 GB of virtual memory for your applications no matter how much memory you actually have.
The simple way around this it to use the 64-bit JVM which runs in your 64-bit OS and is also limited but instead to 192 TB of virtual memory on Windows.
You should try using a 64 bit Java Runtime. It is probably the case that there is no 985 MB large one-piece memory chunk free within the 32-bit address space of your computer (the 32 bit address space 4GB). When you use a 64 bit Java Runtime, Java can allocate the memory within the 64 bit address space, in which the free memory is much more likely to be available.
It doesn't matter that your JAR file was built using a 32 bit version.
The answer to your question may lie in the fact that Windows tries and fails to find a contiguous block of memory that is large enough: see http://javarevisited.blogspot.nl/2013/04/what-is-maximum-heap-size-for-32-bit-64-JVM-Java-memory.html. (Though this suggests that other processes are hogging memory, which seems to be contradicted by your last remark.)

java.lang.OutOfMemoryError: PermGen space error, possible memory leak with Tomcat or PHP-Java Bridge?

OS: Windows Server 2008 R2 SP1
Web Server: IIS 7.5
JSP/Servlet Engine: Tomcat 5.5.28 (32-bit)
PHP: 5.4.14
Java: JRE SE 1.6.0_20 (32-bit)
Apache Isapi Connector hooks into Tomcat from IIS
PHP-Java Bridge 6.2.1
BMC AR System 7.5 Patch 6
Tomcat Initial and Max Memory: 1024 MB, 1024 MB
I am using a Java web application called AR System. After installing the PHP-Java Bridge, I started seeing java.lang.OutOfMemoryError: PermGen space error in the Tomcat logs. (I see in Windows Task Manager that there are 6 PHP-CGI.exe processes, all similar in memory footprint, give or take 5 MB). It would occur every other day or so and then shortened to every day, sometimes twice a day. Consequently, the application hangs and I have to restart it. And I added a Windows Task to restart Tomcat during non-peak hours to give me some cushion. I suspected a memory leak and started doing some research. Normally, Tomcat sits at around 300-350 MB. With the PHP-Java Bridge, memory jumped up significantly. In fact, the error has occurred anywhere from 450-600 MB.
I learned that default PermGen is 64MB and PermGen should be set to 1/4, up to 1/3 of Tomcat memory (sorry, I don't recall the link). Tomcat is running under Windows Services at this point, and I added the following to its properties:
-XX:+UseConcMarkSweepGC
-XX:+CMSPermGenSweepingEnabled
-XX:+CMSClassUnloadingEnabled
-XX:PermSize=128M
-XX:MaxPermSize=256M
I enforced GC on PermGen memory and increased the size from the default 64 MB size to 128-256 MB. Memory went up all the way to 800-850 MB, slowly, but it wasn't hanging during peak hours, albeit I still had Tomcat intentionally restart during non-peak hours, via a Windows Task. If I take off the restart, it MIGHT eventually hang but I haven't tried it.
I still suspected a memory leak. I installed a trial version of AppDynamics to monitor the application, its memory, and run leak detection. Additionally, to use tools like VisualVM and Memory Analyzer (MAT), I disabled The Tomcat Windows service and ran Tomcat from the Windows Command Line, via catalina.bat. I appended Java Options to the file; I made sure Tomcat memory was 1024 MB, Perm Gen was 128/256 MB, and ensured PHP-Java Bridge and AppDynamics was running. As of right now, PermGen is holding at 163 MB used, and AppDynamic's Automatic Leak Detection did not detect any leaks with any Java Collections.
I fired up MAT, created a heap dump and analyzed for leaks. When I ran it yesterday, it found three possible suspects:
net.sf.ehcache.Cache
net.sf.ehcache.store.DiskStore
org.apache.catalina.loader.WebappClassLoader
When I ran it today, it found 2 possible suspects:
java.util.HashMap
org.apache.jasper.servlet.JasperLoader
So, with MAT and AppDynamics, it appears that no memory leaks were detected for classes directly related to the PHP-Java Bridge JAR files. I haven't tried using Plumbr, but I can't find the free beta version. The free version detects leaks, but you have to pay to see it.
Again, I don't have a source link at this time, but I recall reading that Tomcat 5.x can have performance and memory leak issues. Of course, that doesn't mean everybody will have those issues, just a select number. I know Tomcat 6 and Tomcat 7 redesigned their memory management or how they structure memory. I also did speak with someone from BMC, the maker of AR System, and they said the current version of AR System I'm using could suffer from performance and memory issues. But, again, none of this was a problem before the PHP-Java Bridge. It was only after I installed it that this PermGen memory issue started.
Since the tools above did not report any leaks, does that mean there are no leaks and PHP-Java Bridge just needed more than 64 MB PermGen memory? Or, is there an inherit problem with my version of Tomcat and installing the PHP-Java Bridge just broke the proverbial camel's back?
Upgrading to a newer version of AR System and Tomcat is not an option. If there is a leak, I can uninstall the PHP-Java Bridge or continue trying to find a leak and fix it.
Any help would be appreciated.
Thank you.
Update 1
With MAT, I looked at the thread overview and stacks and you can see below that the PHP-Java Bridge contributes about 2/3 of the total heap memory of Tomcat. That's a lot of memory! I think there is a leak, I do. I can't find any information on the PHP-Java Bridge having inherit memory leak issues. But, to me, it appears that the problem is not that Tomcat is leaking. Ideas?
AppDynamics couldn't find any leaks, even when I manually added classes that were suspected in MAT. What I'm wondering is perhaps the PermGen error is a symptom of that case where the program has no leak and needs more PermGen memory allotted. It would be helpful to know if the PHP-Java Bridge is designed to eat a lot of memory, this much memory; maybe it's optimized for 64-bit, since the current setup is a 32-bit Java Web application. If I knew that this bridge needs a lot of memory, I would say OK, fine, and go from there. But it certainly appears as if there is a memory leak somewhere in the chain.
Update 2
I've been running Plumbr now for 2 hours and almost 10 minutes. I see that Tomcat memory is shooting up to 960 MB and probably will continue to climb. For those familiar with the program, the Java web application has been analyzed 3 times. So far, no leaks have been reported. If it stays this way, then the two conclusions I've arrived at are a) there are no leaks or b) there is a leak and, somehow, both AppDynamics and Plumbr missed it. If there are truly no leaks with this set of applications working together, then it must be that the Bridge uses a lot of memory and needs more PermGen memory than Tomcat's default, 64 MB -- at the very least, for 32-bit Java web applications.

Java Heap Size for Zend Studio, soft limit reached, Robust hardware

I have a computer with Intel I7 2600 3.4Ghz processor, 32GB RAM, Windows 7 professional x64, JVM updated.
In Zend Studio when run Source -> Format Code over many files, Zend crash with warning: Java Heap Size.
I read about setting values in ZendStudio.ini, my relevant settings:
-Xms1089M
-Xmx1089M
-XX:MaxPermSize=256m
But I can't increment these limit.
Any alternative for fix this problem?
Why can't you increment? 32 bit JVM?
UPDATE: Did some research. While it is possible to edit Zend Studio's JVM usage,
This support forum post states 32 bit JVM is needed (I guess they use 32 bit native DLLS.
A 32 bit JVM is limited to about 1.5 GB addressable space. You might be able to tweak things further, but it's gonna be a stretch.
Therefore your only solutions are mostly out of your hands
Zend Studio updates to 64 bit support
Zend Studio adjusts memory usage
You figure out a way not to use as much memory yourself.

download the JRockit 5 jre

I want to download Bea JRockIt 5 because the JRE doesn’t seem to be able to allocate VM more than 1.6 GB.
please i not find the link for download the JRockIT jre
I use machine 32 bits windows7 and ram 3GB.
Thanks in advance
The bottom line is that the limit you are seeing is not actually a JVM imposed limit. So changing to JRockit is not going to help.
Most 32-bit Windows operating systems limit the virtual memory for a user application (such as a JVM) to 2Gb. However, there is a boot switch for Windows Server 2003 that enables applications up to 3Gb ... on hardware that supports PAE : http://msdn.microsoft.com/en-us/windows/hardware/gg487508.aspx.
Your alternatives are:
If you are running Windows Server 2003 - do what the link says.
Switch to 32 bit Linux or 32 bit Solaris. Both allow more than 2Gb for user applications.
Switch to a 64 bit operating system.
I don't know why a simple Google search didn't suffice, but this is clearly available on OTN.
As far as allocation of memory for the JVM is concerned, it is unlikely that you will be able to get any amount more than 2GB. See this related question and the most voted answer.

Why is there such a big difference in memory use of a Java application in Windows XP 32 vs Windows 7 64

I have a little Java application that I wrote for recording my work activities. Since I have it open all day, every day, one of the things that originally concerned me as to choice of language is the amount of memory it would use.
Happily, under Windows XP I it would typically consume about 5 MB when minimized and 12 or so when maximized, and happily runs with -Xmx5M (memory consumption according to Windows Task Manager).
When I upgraded my home PC with newer hardware, and at the same time, to Windows 7 64, (although I installed and am using the 32 bit JVM), I immediately noted that the JVM for this application now reports 68 MB+ always... and that's with -Xmx5M -Xss16K, according to Task Manager's "Working Set".
Both the old and new machines had/have 4 GB of RAM, of which 512 MB is used by video. Both were running recent builds of Java 6 - about update 15 for WinXP, and now update 24 for Win7. The application footprint on disk is 70 K in 12 classes. Moreover, my work computer is still Windows XP, running Java 6_24, and it shows about 12 MB for this identical application - and by identical I mean literally that, since the two systems are sync'd for all my development tools.
As a developer, I need to understand the reasons why my applications appear to chew up so much memory.
Can anyone shed some light on this, and suggest how to meaningfully reduce the memory footprint for a Java 6 application?
Edit
The answer may be in an excessive PermGen size. According to JVisualVM, I have a heap of:
Size: 5.2 MB, Used: 4.3 MB (peak) and Allocated 6.2 MB.
but for the PermGen
Size: 12.5 MB, Used: 4.6 MB (peak) and Allocated 67.1 MB.
So is it possible that the 68 MB shown in Task Manager in Win 7 is simply requested but unassigned virtual memory?
EDIT 2
Reducing PermGen to 12 MB had no effect on the process RAM, but JVisualVM did show it reduced (apparently 12 MB constitutes some sort of minimum, because going lower than that had no effect in JVVM).
The 64 bit OS uses 64 bits as the size of pointers while a 32 bit OS uses 32 bits. That might just be one of the reasons though.
Remember that everything in Java is a pointer (for the most part) so when switching to a 64 bit machine, with 64 bit memory addresses, your pointers double in size.
There is an option in the JVM (-XX:+UseCompressedOops) to turn on compressed object pointers. This will put your memory usage near the levels you saw on 32 bit machines.
For the 64-bit JVM you can specify an option that will reduce the overhead of 64-bit addressing. As long as the heap is under 32GB it can essentially compress the pointers back to 32-bit. In a typical Java application this saves about 40% of the memory. See Compressed oops in the Hotspot JVM for more details. Here's the option for it:
-XX:+UseCompressedOops
Note that if you use a 32-bit JVM on a 64-bit OS that you won't pay the overhead of 64-bit memory addresses (although there's a different overhead to pay there in translation, yet it's very minor).
I believe that Windows 7 doesn't report memory use the same as XP either (I don't have a reference offhand though). So for a fair comparison of 32-bit vs 64-bit you need to run both on the same version of Windows.
This has nothing to do with the operating system being 64-bit - Windows XP and Windows 7 use RAM in very different ways.
Because of this, Windows 7 will almost always report all programs as using more memory than Windows XP did. Don't worry about this - this is just a result of Windows 7 using your memory the way it should be: as a cache.
While it's not the whole story, the PermGen size is 30% larger on 64-bit plaforms:
-XX:MaxPermSize - Size of the Permanent Generation.
[5.0 and newer: 64 bit VMs are scaled
30% larger; 1.4 amd64: 96m; 1.3.1
-client: 32m.]
Java 6 HotSpot VM Options

Categories