Thursday, March 31, 2011

assembly.GetExportedTypes() show different result

Why does assembly.GetExportedTypes() show different result in C# and VB.NET?

These two give different results

var v = from a in AppDomain.CurrentDomain.GetAssemblies() from b in a.GetExportedTypes() select b; 
v.Count(); 

Dim v = From a In AppDomain.CurrentDomain.GetAssemblies(), b In a.GetExportedTypes()     Select b v.Count()
From stackoverflow
  • When you compile a VB.NET assembly, it includes some extra "helper" types. Use Reflector to have a look at your compiled assembly to see what I mean.

    I'm pretty sure you'll find that the only assembly with any differences in is the one you're using to do the reflection - i.e. the one which is built with either C# or VB.NET, depending on your scenario.

    EDIT: It depends on exactly how you define your classes.

    However, again this is only relevant to the code being compiled by the C# or VB compiler. When you call GetExportedTypes it doesn't matter what language you're calling from. You're getting confused by the fact that you're only writing out the total count. Here are two short but complete programs to show the difference:

    C#

    using System;
    using System.Reflection;
    
    public class ShowTypeCounts
    {
        static void Main()
        {
            AppDomain domain = AppDomain.CurrentDomain;
            foreach (Assembly assembly in domain.GetAssemblies())
            {
                Console.WriteLine("{0}: {1}",
                                  assembly.GetName().Name,
                                  assembly.GetExportedTypes().Length);
            }
        }
    }
    

    Results:

    mscorlib: 1282
    ShowTypeCounts: 1
    

    VB

    Imports System
    Imports System.Reflection
    
    Public Module ShowCounts
    
        Sub Main()
            Dim domain As AppDomain = AppDomain.CurrentDomain
    
            For Each assembly As Assembly in domain.GetAssemblies
    
                Console.WriteLine("{0}: {1}", _
                                  assembly.GetName.Name, _
                                  assembly.GetExportedTypes.Length)
    
            Next
        End Sub
    
    End Module
    

    Results:

    mscorlib: 1282
    ShowTypeCounts: 1
    

    As you can see, the results are the same - but if you remove "public" from either piece of code, the ShowTypeCounts result goes down to 0. This isn't a difference of how GetExportedTypes works between languages - it just depends on what types you're actually exporting.

    My guess is that in your console apps, one had a public type and the other didn't.

    Jon Skeet : Yes, one of the assemblies that's being reflected into *is* that console app though.

What can cause a UIView to be arbitrarily removed from the hierarchy?

I have an iPhone app that, for some users, sometimes behaves as if with the main UIView has been removed from the view hierarchy. It always happens coincident with a significant event in the game. Other Core Graphics-drawn UIViews that are above it in the z-order remain, but the main one (an OpenGL view) appears to be gone, leaving the background (a solid color).

The app does not crash (it keeps running, without the view), and this seems to happen very consistently for affected users. Unfortunately I am not able to reproduce it.

I suspect a memory issue -- that would be the easiest explanation -- but based on my reading it looks like didReceiveMemoryWarning only deallocs views that aren't visible, and aside from that the memory usage for my app is pretty small. Also, the "significant event" only results in OpenGL drawing and a SoundEngine call -- no view manipulation.

Anybody out there seen something like this before?

From stackoverflow
  • Yes, infact one of my applications very occasionally exhibits this problem and it does seem to be memory related.

    I have had no success tracking it down either by debugging or analyzing the program flow. I have verified that the view in question is destroyed and not just hidden in some way.

    It happens so infrequently that I haven't looked into it to deeply, but I do think it's caused by something in the OS in some way,

    Adam Preble : Check out my self-supplied answer below; it may help your app too.
  • As is made clear in the SDK documentation, when your app is running low on memory, views that are not in use can be collected. When it's needed again, it's re-created. This is to conserve precious iPhone resources. Your best bet is to retain the view so it can't be released.

    Andrew Grant : If the view in question is visible it's a pretty good bet that it's "in use"
    Adam Preble : August - Thanks for your attempt to help, but please read my question carefully. As Andrew points out the view in question is in use.
  • You can easily test low memory in the simulator to debug this problem if it is memory related.

    Adam Preble : True; unfortunately it does not reproduce the problem (or appear to have any effect on the app).
    Andrew Grant : All the simulator does is call the low memory methods on your classes. It does not simulate the OS running low on resources. Sadly there's a number of reasons it's called a simulator and not an eumlator.
  • The problem ended up being an uncaught NSException (from a third party library) thrown in the app's timer thread, which killed the timer thread but not the rest of the app. The good news is that crash reports are generated in this case, which can make tracking it down much easier if you know to look/ask for them.

Java (ME) on Windows Mobile

Does anyone have experience deploying Java ME apps to Windows Mobile? What are the high-level steps to getting started with this, and are there any major drawbacks?

From stackoverflow
  • Just beginning with the Samsung i900. FileConnection seems all bad with no obvious access to the internal hard drive or the memory card. Worried about the Applix jBlend base port.

    I hope others have a better experience of java on windows mobile.

  • Well at first you need to install a JVM on your device (if one isn't already installed). There are currently two players for this:

    • NSI Creme. This is a robust product but it only supports CDC profile (no MIDlets) and you need to buy a license for at least 1000 devices or so.
    • IBM J9. This has CLCD support and can run MIDlets. There is a demo version, but I wasn't able to find a download link. May be IBM has stopped supporting it.

    Some devices have a JVM pre-installed, but it is difficult to rely on certain profiles being present. Unless you are targeting a single device, I would say that is better to avoid J2ME for Windows Mobile.

  • kgiannakakis is right with the JavaVM that needs to be installed on Windows Mobile devices, but this only counts for older devices. Windows Mobile 5 and 6 come with a pre-installed Microsoft Java VM which works. Basically.

    You can actually just compile your J2ME application to a jar file, copy it on your Windows Mobile device and start it. That's pretty much it.

    As with all generic JavaME VM's you will not be able to access internal API's / hardware which is not accessible from within the standard CLDC/MIDP libraries the JavaVM you are using, supports.

.htaccess with or without slash

What do I need to do to the following rewrite rule to make it so it works whether or not their is a slash at the end of the URL?

ie. http://mydomain.com/content/featured or http://mydomain.com/content/featured/

RewriteRule ^content/featured/ /content/today.html
From stackoverflow
  • Use the $ to mark the end of the string and the ? to mark the preceding expression to be repeated zero or one times:

    RewriteRule ^content/featured/?$ content/today.html
    

    But I recommend you to stick to one notation and correct misspelled:

    # remove trailing slashes
    RewriteRule (.*)/$ $1 [L,R=301]
    
    # add trailing slashes
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule .*[^/]$ $0/ [L,R=301]
    
    Unkwntech : +1 mostly for the additional info, although I was gonna' give it to you anyway.

If I want to rebase my DLL's, how do I go about doing it?

This is a continuation of this question.

I'm in the process of testing whether rebasing the .NET DLLs, and NGENning them will provide me with more shared code in memory on terminal servers.

However, my plan seems to have a flaw, and it's that I seem unable to find a working method to figure out a working set of addresses.

What I thought I could do was as follows:

  1. Just build and NGEN everything
  2. Start the program, ensuring all the DLL's have been loaded
  3. Use LISTDLLS /R PROGRAMNAME to get a list of current in-use addresses for the running instance
  4. Use the addresses of those DLL's that was remapped as the new base-address for those dll's
  5. UN-NGEN everything, and start back at 1

However, this has turned into a Schrödinger exercise because the act of rebasing some DLLs apparently either change the load order or how the operating system relocates other DLLs.

For instance, let's say that after the initial run I have a list that says that DLLs A, B and C needs to be at address 1000, 2000 and 3000. There's no mention of DLL D, E and F, which are also part of the same system. Presumably these were loaded at their current baseaddress, otherwise I would assume LISTDLLS would tell me about that.

So I change the address of A, B, C, repeat everything, and now DLL C, D and E have been relocated. A and B are now OK, E and F now became relocated, and C is still being shuffled around.

I realize that this exercise is somewhat a futile one, since regardless of what I figure out on my machine, DLLs being used and injected on the target terminal server might disturb this picture but I thought that if I could at least make sure some of the DLLs could be located at their prescribed base address then the amount of shared code between multiple instances of the same program would go up. Just saying, just so that there is no need to "remind" me of that :)

Since the original base addresses of all our DLLs was the default, which meant every DLL (possibly except the first one loaded) was relocated, and thus mapped to the page file, I would think that there would be a potential gain above 0.

Any advice?

From stackoverflow
  • You can find out a DLLs preferred loading address and memory ranges using DUMPBIN (comes within Visual Studio) and do your planning based on those numbers.

    dumpbin /headers would give you:

     7DC90000 image base (7DC90000 to 7DD5FFFF)
    

    If you plan according to preferred loading addresses you should have no problems.

How to detect memory leak / battery drain in an iPhone app

I'm afraid I introduced a memory leak or something to version 1.2 of my iPhone app. When I use 1.2 version I notice that my battery drains a lot quicker then with 1.1 version. For comparison, with 1.1 version the battery would last whole day and still have plenty of juice in the evening but with 1.2 I find that I have to plug it in mid afternoon.

Would a memory leak (or a lot of them) cause an increased battery drainage, or do I have something else going on?

The only interesting thing my app uses is AVAudioPlayer class to play some caf audio files. Other than that it's just couple of views with a table view.

I do call AudioSessionSetAcvie(false) in my applicationWillTerminate method, so I don't think it's the audio session that's causing this. I don't have to have my app active for the battery to get drained. It's enough to use it for a while and then exit. So I'm pretty sure I'm leaving something behind, I'm just not sure what.

I tried playing with Instruments tool, but it looks like you can't used with the app running on the device (for some reason my app stopped working in the Simulator)

Any ideas on how to go about finding what's causing the battery to drain?

From stackoverflow
  • Memory leaks will not cause increased battery usage. However, if a memory leak persists, eventually you will get a memory warning, and if you can't clean up enough memory, your application will be killed.

    Increased battery utilization usually means something is causing your code to continue running. The best way to tackle this problem is to run your application under Instruments (with Sampler probably) and let it sit there in the state that you're confident it usually runs the battery down. Inspect the results of Sampler, and if you have code running, you'll be able to see the stack trace for it.

    Hopefully once you've located what code is running, it will become apparent how to stop it.

    subjective-c : I notice the battery draining even when my app is not running. So is it possible that some parts of my app are still executing even when I exit my app?
    NilObject : I highly doubt it. So you're noticing a faster battery drain when comparing a freshly booted phone to a freshly booted phone after quitting your application?
    subjective-c : Right. But I don't have any hard evidence, just my observation. I'm beginning to think now that it's not related to my app.
  • Memory leaks won't cause increased battery usage, as Nilobject says.

    I would try commenting out various areas of functionality, one at a time, to try to narrow down the area that is causing the problem. In your case, the first thing to try is obviously to remove the audio. If, once you've done that, battery usage is back to normal, you know where to look more deeply.

  • (for some reason my app stopped working in the Simulator)

    I would fix that and use instruments to fix the performance bug. It's never a good idea to fix the difficult defect and leave the easy one.

    subjective-c : I don't really feel like spending time debugging Apple's Simulator. The damned thing never really worked well for me, so I stopped using it. I develope with iPhone connected.

NSData - Which is better in terms of memory usage: initWithContentsOfURL or NSURLConnection

Hi

I want to get an NSData object's contents from a URL. What is the more efficient way of doing this in terms of memory usage dataWithContentsOfURL (or initWithContentsOfURL) or using NSURLConnection?

Should I use

NSData *data = [[NSData alloc] initWithContentsOfURL:myURL]

or

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
From stackoverflow
  • Pretty sure they are quite equivalent.

  • I don't know the internals of Apple's code but I would guess NSData's initWithContents of URL uses NSURLConnection internally. Memory usage differences will be negligible.

    Using the asynchronous apis of NSURLConnection would allow you to be more memory efficient by handling data as it came in but (without knowing what you are actually doing) I think this is a fairly agressive optimisation that you should leave until you have working code.